Rust 中大量线程的性能下降
Performance degradation for high numbers of threads in Rust
我正在用 Rust 创建无闩锁并发 HashMap
。吞吐量曲线看起来与我预期的一样,最多约 16 个线程,此时性能下降。
吞吐量(MOps/sec)与线程数
我使用了具有 48 个 vCPU 和 200GB RAM 的 Google 云实例。我尝试了 enabling/disabling 超线程,但没有明显的结果。
下面是我生成线程的方式:
for i in 0..num_threads {
//clone the shared data structure
let ht = Arc::clone(&ht);
let handle = thread::spawn(move || {
for j in 0..adds_per_thread {
//randomly generate and add a (key, value)
let key = thread_rng().gen::<u32>();
let value = thread_rng().gen::<u32>();
ht.set_item(key, value);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
我没主意了;我的 Rust 代码适合多线程吗?
如果您的所有线程都将所有时间都花在您的无锁数据结构上,那么是的,一旦您拥有足够多的线程,就会发生争用。有了足够多的作者,他们会更频繁地争夺 table 中的同一缓存行。 (此外,花在 PRNG 上的时间可能不会隐藏对缓存或 DRAM 的共享带宽的争用)。
您可能会开始遇到更多的 CAS 重试和类似问题,包括任何争用退避机制,而不仅仅是停滞不前。此外,线程将遭受缓存未命中,甚至 来自某些原子读取;并非所有内容都是原子 RMW 或写入。
这不是无锁数据结构的正常用例;通常,您将它们与执行重要工作的代码一起使用,而不是敲打它们,因此实际竞争很低。此外,哈希图的实际工作负载很少是只写的(尽管如果您只想删除某些内容,则可能会发生这种情况)。
读取与读者数量的关系非常好,但写入会引起争用。
我正在用 Rust 创建无闩锁并发 HashMap
。吞吐量曲线看起来与我预期的一样,最多约 16 个线程,此时性能下降。
吞吐量(MOps/sec)与线程数
我使用了具有 48 个 vCPU 和 200GB RAM 的 Google 云实例。我尝试了 enabling/disabling 超线程,但没有明显的结果。
下面是我生成线程的方式:
for i in 0..num_threads {
//clone the shared data structure
let ht = Arc::clone(&ht);
let handle = thread::spawn(move || {
for j in 0..adds_per_thread {
//randomly generate and add a (key, value)
let key = thread_rng().gen::<u32>();
let value = thread_rng().gen::<u32>();
ht.set_item(key, value);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
我没主意了;我的 Rust 代码适合多线程吗?
如果您的所有线程都将所有时间都花在您的无锁数据结构上,那么是的,一旦您拥有足够多的线程,就会发生争用。有了足够多的作者,他们会更频繁地争夺 table 中的同一缓存行。 (此外,花在 PRNG 上的时间可能不会隐藏对缓存或 DRAM 的共享带宽的争用)。
您可能会开始遇到更多的 CAS 重试和类似问题,包括任何争用退避机制,而不仅仅是停滞不前。此外,线程将遭受缓存未命中,甚至
这不是无锁数据结构的正常用例;通常,您将它们与执行重要工作的代码一起使用,而不是敲打它们,因此实际竞争很低。此外,哈希图的实际工作负载很少是只写的(尽管如果您只想删除某些内容,则可能会发生这种情况)。
读取与读者数量的关系非常好,但写入会引起争用。