OpenMP - 并行 For 循环

OpenMP - Parallel For Loop

我使用二维向量。我有两个操作:

您需要使用#critical 指令才能正确访问共享变量:

#include <omp.h>

main()
{

   int x; 
   x = 0;

   #pragma omp parallel shared(x) 
   {

      #pragma omp critical 
      x = x + 1;

   }  /* end of parallel section */
}

示例取自:https://computing.llnl.gov/tutorials/openMP/#CRITICAL

如果我是你,我会想一些不同的事情(不幸的是你不能在这种情况下使用#reduction,但你绝对可以重新调整代码以获得相同的结果)。

不幸的是,在这种情况下,OpenMP 无法阻止数据竞争。 shared 子句允许所有线程查看向量变量,但它不对它们的访问进行排序。 Vector 的 push_back 函数不是线程安全的,因为它可能导致重新分配(增长)vector 的底层存储。

此代码可以并行化,但它的可扩展性取决于您愿意投入多少实施工作。要确定适当的工作量,请确定这部分需要您整个工作量的时间应用。这里有两种(在许多可能的)方法来并行化您的问题:

  • 性能稳定的低工作量 - 制作 tempVector 1D 和与 objVector 相同的大小。不是将带有索引列表的 4 个向量放入 objVector,而是将 tempVector[i] 设为 0-3 objVector[i] 的哪个 bin。这可以通过一个简单的 openmp parallel for 来完成。稍后使用 tempVector 时,获取特定 bin 的所有值将涉及扫描所有 tempVector。如果只有 4 个 bin,这实际上可能表现得很好。
  • 更多努力和最佳可伸缩性 - 为每个线程提供它自己的本地 tempVector 并使用 openmp parallel for 跨 objVector 并行化。这样每个线程都可以使用 vector 的 push_back 函数,因为它们是唯一访问该 vector 的线程。将 tempVector 的所有本地副本合并到一个共享的 tempVector 中可以通过原子地添加大小然后批量复制片段来完成。