Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 只读存储器访问的线程安全_C_Thread Safety_Pthreads - Fatal编程技术网

C 只读存储器访问的线程安全

C 只读存储器访问的线程安全,c,thread-safety,pthreads,C,Thread Safety,Pthreads,我在C中实现了Barnes-Hut重力算法,如下所示: 建造一棵群星之树 对于每个恒星,遍历树并从每个适用节点应用重力 更新恒星的速度和位置 阶段2是最昂贵的阶段,因此通过划分星集并行实现。例如,对于1000颗星和2个线程,我有一个线程处理前500颗星,第二个线程处理后500颗星 实际上,这是可行的:与非线程版本相比,在双核机器上使用两个线程时,计算速度提高了约30%。此外,它产生与原始非线程版本相同的数值结果 我关心的是两个线程同时访问同一个资源(即树)。我没有向线程工作者添加任何同步,因此他

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

  • 建造一棵群星之树
  • 对于每个恒星,遍历树并从每个适用节点应用重力
  • 更新恒星的速度和位置
  • 阶段2是最昂贵的阶段,因此通过划分星集并行实现。例如,对于1000颗星和2个线程,我有一个线程处理前500颗星,第二个线程处理后500颗星

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

    我关心的是两个线程同时访问同一个资源(即树)。我没有向线程工作者添加任何同步,因此他们可能会在某个时候尝试从同一位置读取。虽然访问该树是严格只读的,但我不能100%确定它是否安全。当我测试它时,它已经工作了,但我知道这不能保证正确性

    问题

    • 我是否需要为每个线程制作树的私有副本
    • 即使是安全的,从多个线程访问同一内存是否存在性能问题
    更新好奇者的基准测试结果:

    机器:英特尔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我使用了一个线程池,与两个屏障同步。与每帧重新创建线程相比,这没有明显的性能优势。

    如果数据是只读的,则不需要为每个线程创建树的私有副本。这是共享内存线程模型提供的最大优势


    我不知道这种型号有任何性能问题。如果有的话,速度应该更快,这取决于您的CPU是否可以共享部分缓存。

    您不指定数据的结构,但一般来说,同时从多个线程读取内存是安全的,不会带来任何性能问题。只有当有人在写作时,你才会遇到问题

    有趣的是,你说两个线程的加速率只有30%。如果你有一台闲置的机器,两个或更多的CPU,并且只有只读共享数据(即没有同步),我希望速度能提高近50%。这表明您的操作实际上完成得非常快,以至于创建线程的开销在您的数量中变得非常重要。您是在超线程CPU上运行的吗?

    我怀疑这是阿姆达尔定律——我只对最初占用80-90%运行时间的进程的一部分进行了并行处理。另一件事是,是的,我每次都在重新创建线程。我还没有确定这有多贵。