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 在 并发
每月116 次下载
在 2 个 Crates 中使用 (通过 scanflow)
12KB
154 行
rayon-tlsctx
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