并行for循环的C ++ OpenMP指令?

时间:2011-10-06 06:24:13

标签: c++ openmp

我正在尝试特定代码段上的OpenMP。不确定该代码片段是否需要更新,可能是为了顺序实现而设置得过于严格。无论如何这里是我试图并行化的(伪)代码:

#pragma omp parallel for private(id, local_info, current_local_cell_id, local_subdomain_size) shared(cells, current_global_cell_id, global_id)
for(id = 0; id < grid_size; ++id) {
   local_info = cells.get_local_subdomain_info(id);
   local_subdomain_size = local_info.size();
   ...do other stuff...
   do {
      current_local_cell_id = cells.get_subdomain_cell_id(id);
      global_id.set(id, current_global_cell_id + current_local_cell_id);
   } while(id < local_subdomain_size && ++id);
   current_global_cell_id += local_subdomain_size;
}

这在顺序意义上完全有意义(在盯着它一段时间之后),这也可能意味着它需要为OpenMP重写。我担心的是current_local_cell_id和local_subdomain_size是私有的,但是current_global_cell_id和global_id是共享的。

因此在内循环之后语句 current_global_cell_id + = local_subdomain_size

do {
  ...
} while(...)
current_global_cell_id += local_subdomain_size;
我怀疑,

可能会导致OpenMP设置出错。如果有任何OpenMP专家可以提供一些特殊的OMP指令,我可以用来对代码进行最小的更改,但仍然可以使用OpenMP用于这种类型的for循环,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

我不确定我理解你的代码。但是,我认为你真的想要某种并行积累。

你可以使用像

这样的模式
 size_t total = 0;
 #pragma omp parallel for shared(total) reduction (+:total)
 for (int i=0; i<MAXITEMS; i++)
 {
      total += getvalue(i); // TODO replace with your logic
 }

 // total has been 'magically' combined by OMP

在相关说明中,当您使用gcc时,您可以使用__gnu_parallel::accumulate的{​​{1}}替代品替换std::accumulateexactly相同。见Chapter 18. Parallel Mode

 size_t total = __gnu_parallel::accumulate(c.begin(), c.end(), 0, &myvalue_accum);

您甚至可以使用-D_GLIBCXX_PARALLEL进行编译,如果可能的话,这将使std算法的所有使用自动并行化。 除非你知道自己在做什么,否则不要使用它!通常,性能会受到影响,并且由于意外的并行性而引入错误的可能性是真实的

答案 1 :(得分:1)

更改循环内的id是不正确的。没有办法将循环调度到不同的线程,因为循环步骤不会产生可预测的id值。

为什么你在while循环中使用id?