Rust中大量线程的性能下降

杰克·特鲁斯科夫斯基

我正在HashMapRust中创建无闩锁并发吞吐量曲线看起来就像我期望的那样,最多可达16个线程,此时性能将下降。

吞吐量(MOps /秒)与线程数

吞吐量(MOps /秒)与线程数

我使用了具有48个vCPU和200GB RAM的Google Cloud实例。我尝试启用/禁用超线程,但是没有明显的结果。

这是我产生线程的方法:

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代码对多线程正确吗?

彼得·科德斯

如果您所有的线程都将所有的时间都花在锤击无锁数据结构上,那么一旦拥有足够的线程,您将获得竞争。如果有足够的编写者,他们将更频繁地争夺表中的同一缓存行。(此外,在PRNG中花费的时间可能不会隐藏争用共享带宽缓存或DRAM的争用)。

您可能会开始进行更多的CAS重试和类似的工作,包括任何争用退避机制,而不仅仅是高原。此外,线程将遭受高速缓存未命中,甚至会从某些原子读取中清除内存顺序的错误推测流水线并非一切都是原子RMW或写入。

这不是无锁数据结构的正常用例。通常,您将它们与执行重要工作的代码一起使用,而不是对其进行锤击,因此实际争用较低。此外,哈希映射的实际工作负载很少是只写的(尽管如果您只想对某项进行重复数据删除,则可能会发生这种情况)。

读取与读者数量的比例很好,但是写入会引起争用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章