在C ++ 11基于范围的循环中使用OpenMP吗?


71

是否有任何反指示?还是行为明确?

#pragma omp parallel for
for(auto x : stl_container)
{
   ...
}

因为似乎OpenMP规范仅对c ++ 98有效,但我想由于C ++ 11线程可能存在更多不兼容问题,这里不使用它们。我还是想确定。


1
+好问题。也想知道。
lulyon

Answers:


47

OpenMP 4.0规范已几天前完成并在此处发布。它仍然要求并行循环应采用规范形式(第2.6节,第51页):

for (init-expr ; test-expr ; incr-expr) 结构化块

该标准允许在所有表达式中使用提供随机访问迭代器的容器,例如:

#pragma omp parallel for
for (it = v.begin(); it < v.end(); it++)
{
   ...
}

如果您仍然坚持使用C ++ 11语法糖,并且(相对)要​​花费大量时间来处理的每个元素stl_container,则可以使用单一生产者任务模式:

#pragma omp parallel
{
   #pragma omp single
   {
      for (auto x : stl_container)
      {
         #pragma omp task
         {
            // Do something with x, e.g.
            compute(x);
         }
      }
   }
}

任务分配会产生一定的开销,因此,如果compute(x);花费很少的时间来完成,使用这种模式将毫无意义。


我认为迭代器是现在的方法,但是如果您想用gcc编译代码,则需要用<=代替!=,否则会出现“无效的控制谓词”错误。顺便问一下,你知道为什么吗?
DarioP


在该网站上,他们不会在周期之前进行任何实用性检查。只是尝试编译它:)
DarioP

3
@DarioP!=是一种Intel主义-该标准不允许使用它,但是icpc足够聪明,可以推断出循环中正在发生的事情。我纠正了它。这也是需要随机访问迭代器的原因之一-常规迭代器仅提供==!=运算符。
赫里斯托·伊利耶夫

似乎至少使用Apple Clang 12.0.0,std::map没有随机访问迭代,因此该<关系不起作用。
oarfish

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.