gpt4 book ai didi

c - 只读内存访问的线程安全

转载 作者:太空狗 更新时间:2023-10-29 15:17:06 25 4
gpt4 key购买 nike

我在 C 中实现了 Barnes-Hut 引力算法,如下所示:

  1. 构建星团树。
  2. 对于每颗星,遍历树并应用来自每个适用节点的引力。
  3. 更新恒星速度和位置。

第 2 阶段是最昂贵的阶段,因此通过划分恒星集并行实现。例如。有 1000 颗星和 2 个线程,我有一个线程处理前 500 个星,第二个线程处理后 500 个。

在实践中这是有效的:与非线程版本相比,它在双核机器上使用两个线程将计算速度提高了大约 30%。此外,它产生与原始非线程版本相同的数值结果。

我担心的是两个线程同时访问同一个资源(即树)。我没有向线程 worker 添加任何同步,因此它们很可能会在某个时候尝试从同一位置读取。尽管对树的访问是严格只读的,但我不能 100% 确定它是安全的。它在我测试时有效,但我知道这不能保证正确性!

问题

  • 我是否需要为每个线程制作树的私有(private)副本?
  • 即使安全,多线程访问同一 block 内存是否存在性能问题?

更新 好奇的基准测试结果:

机器:Intel Atom CPU N270 @ 1.60GHz,cpu MHz 800,缓存大小 512 KB

Threads      real      user      sys
0 69.056 67.324 1.720
1 76.821 66.268 5.296
2 50.272 63.608 10.585
3 55.510 55.907 13.169
4 49.789 43.291 29.838
5 54.245 41.423 31.094

0 表示完全没有线程; 1 及以上意味着生成那么多工作线程并让主线程等待它们。我不期望超过 2 个线程的任何改进,因为它完全受 CPU 限制,这就是有多少个内核。有趣的是,奇数线程比偶数线程稍差。

查看 sys 很明显,创建线程是有成本的。目前它正在为每一帧创建线程(因此创建了 N*1000 个线程)。这很容易编程(在我今天早上在火车上的 15 分钟内)。我需要考虑一下如何重用线程...

更新#2 我让它使用线程池,与两个障碍同步。与每帧重新创建线程相比,这没有明显的性能优势。

最佳答案

您没有指定数据的结构,但通常同时从多个线程读取内存是安全的,并且不会引入任何性能问题。如果有人在写作,你只会遇到问题。

有趣的是,您说从两个线程中您只能获得 30% 的加速。如果你有一台空闲的机器,两个或更多的 CPU 和只读共享数据(即没有同步),我希望看到更接近 50% 的速度改进。这表明您的操作实际上完成得如此之快,以至于创建线程的开销在您的数字中变得越来越重要。您是否在超线程 CPU 上运行?

关于c - 只读内存访问的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2762803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com