#thread #rayon #thread-pool #tls

rayon-tlsctx

Rayon 循环的线程局部上下文

4 个版本

0.2.0 2021年5月24日
0.1.2 2021年5月24日
0.1.1 2021年5月21日
0.1.0 2021年5月21日

#695并发

Download history 9/week @ 2024-03-25 34/week @ 2024-04-01 7/week @ 2024-04-08 4/week @ 2024-04-15 662/week @ 2024-04-22 600/week @ 2024-04-29 125/week @ 2024-05-06 18/week @ 2024-05-13 53/week @ 2024-05-20 23/week @ 2024-05-27 16/week @ 2024-06-03 7/week @ 2024-06-10 15/week @ 2024-06-17 10/week @ 2024-06-24 89/week @ 2024-07-08

每月116 次下载
2 个 Crates 中使用 (通过 scanflow)

MIT 许可证

12KB
154

rayon-tlsctx

Crates.io API Docs Build and test MIT licensed

Rayon 线程池的线程局部变量

此crate提供了一个简单的ThreadLocalCtx结构体,允许存储由lambda构建的线程局部状态。

在多线程处理中非常有用,其中需要使用昂贵到无法复制的上下文。最终,将不会比Rayon线程池中的线程数更多的复制发生。


lib.rs:

仅在必要时进行复制

此库提供了一种在Rayon线程池中高效复制值的方法,但通常每个线程只复制一次。它减少了可能昂贵的复制操作的计算时间。

在Rayon递归调度同一作业的另一个实例时,偶尔会发生额外的复制。但最终,对于N个线程,不应该有超过2N个复制。

示例

use rayon_tlsctx::ThreadLocalCtx;
use rayon::iter::*;

const NUM_COPIES: usize = 16;

let mut buf: Vec<u16> = (0..!0).collect();

// Create a thread local context with value 0.
let ctx = ThreadLocalCtx::new(|| {
    // Simulate expensive operation.
    // Since we are building unlocked context,
    // the sleeps will occur concurrently.
    std::thread::sleep_ms(200);
    0
});

let pool = rayon::ThreadPoolBuilder::new().num_threads(64).build().unwrap();

// Run inside a custom thread pool.
pool.install(|| {
    // Sum the buffer `NUM_COPIES` times and accumulate the results
    // into the threaded pool of counts. Note that the counts may be
    // Unevenly distributed.
    (0..NUM_COPIES)
        .into_par_iter()
        .flat_map(|_| buf.par_iter())
        .for_each(|i| {
            let mut cnt = unsafe { ctx.get() };
            *cnt += *i as usize;
        });
});


let buf_sum = buf.into_iter().fold(0, |acc, i| acc + i as usize);

// What matters is that the final sum matches the expected value.
assert_eq!(ctx.into_iter().sum::<usize>(), buf_sum * NUM_COPIES);

依赖项

~1.5MB
~25K SLoC