并行版本的循环不比串行版本快

Il-*_*ima 5 parallel-processing performance multithreading boost-thread atomic-values

我正在用C++编写一个程序来执行特定系统的模拟.对于每个时间步长,执行的最大部分是由单个循环占用.幸运的是,这是非常平行的,所以我决定使用Boost Threads并行化它(我在2核机器上运行).我期望加速接近串行版本的2倍,因为没有锁定.但是我发现根本没有加速.

我实现了循环的并行版本如下:

  • 唤醒两个线程(它们被阻挡在屏障上).
  • 然后每个线程执行以下操作:

    • 以原子方式获取并递增全局计数器.
    • 使用该索引检索粒子.
    • 对该粒子执行计算,将结果存储在单独的数组中
    • 等待工作完成障碍
  • 主线程等待工作完成障碍.

我使用这种方法,因为它应该提供良好的负载平衡(因为每次计算可能需要不同的时间量).我真的很好奇可能导致这种放缓的原因.我总是读到原子变量很快,但现在我开始怀疑它们是否有性能成本.

如果有人有什么想法或任何提示,我会非常感激.我一直在抨击它一个星期,并且剖析没有透露太多.

编辑:问题解决了! 我将详细说明我是如何解决这个问题的.我再次使用gprof,但这次编译时没有优化标志(-O3).然后,分析器立即表明我在函数中花费了不可思议的时间,该函数对每个单独的粒子执行计算:远远超过串行版本.

此功能是虚拟的,可以多态访问.我改变了代码直接访问它,而不是通过vtable和voila'并行版本产生了近2的加速!串行版本的相同更改几乎没有影响.

我不知道为什么会这样,如果有人知道的话会感兴趣!

感谢所有的海报.你们都在某种程度上有所帮助,接受一个答案是非常困难的.

Art*_*yom 2

对该粒子执行计算,将结果存储在单独的数组中

计算量有多大?

  • 一般来说,原子计数器可能会花费数百个时钟周期,并且重要的是要看到您不仅仅增加计数器。
  • 还要尝试查看每个线程做了多少工作 - 它们是否合作良好(即在每个周期中每个线程进行大约一半的粒子)。
  • 尝试将作业细分为更大的块,然后细分为单个粒子(假设 100 个粒子等)。
  • 查看有多少工作是在线程之外完成的。

老实说...看起来你所说的是一个错误。