我正在用C++编写程序以对特定系统进行仿真。对于每个时间步,执行的最大部分是一个循环。幸运的是,这令人尴尬地是并行的,所以我决定使用Boost Threads对其进行并行化(我在2核计算机上运行)。由于没有锁定,我希望加速比串行版本快2倍。但是我发现根本没有加速。

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

  • 唤醒两个线程(它们被隔离在障碍物上)。
  • 然后,每个线程执行以下操作:
  • 以原子方式获取并递增全局计数器。
  • 检索具有该索引的粒子。
  • 在该粒子上执行计算,并将结果存储在单独的数组
  • 等待工作完成的障碍
  • 主线程等待作业完成屏障。

  • 我之所以使用这种方法,是因为它应该提供良好的负载平衡(因为每次计算可能花费不同的时间)。对于可能导致这种速度下降的原因,我真的很好奇。我总是读到原子变量很快,但是现在我开始怀疑它们是否有性能损失。

    如果有人有什么想法要寻找或有任何提示,我将非常感激。我已经为它打了一个礼拜一个星期,而剖析并没有显示太多。

    编辑:问题已解决!
    我将详细说明如何解决此问题。我再次使用gprof,但是这次编译时没有优化标志(-O3)。随即,探查器表明我在该函数上花费了不可思议的时间,该函数对每个单独的粒子执行计算:这比串行版本要多得多。

    此功能是虚拟的,可以多态访问。我更改了代码以直接访问它,而不是通过vtable来访问,瞧,并行版本产生了将近2倍的加速!串行版本上的相同更改几乎没有效果。

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

    感谢所有的海报。大家都提供了一定程度的帮助,很难接受一个答案。

    最佳答案



    计算有多繁重?

  • 一般而言,原子计数器可能要花费数百个时钟周期,因此
    看到您不仅增加了计数器。
  • 还尝试查看每个线程完成了多少工作-它们配合得好吗(即,在每个循环中,每个线程处理大约一半的粒子)。
  • 尝试将工作分割为更大的块,然后再划分为单个粒子(比如说100个粒子,依此类推)。
  • 查看线程外完成了多少工作。

  • 老实说...看来您在说的是一个错误。

    10-02 01:56