C Openmp:增加循环迭代次数

C Openmp:增加循环迭代次数,c,for-loop,numbers,iteration,openmp,C,For Loop,Numbers,Iteration,Openmp,我有这个并行的循环 struct p { int n; double *l; } #pragma omp parallel for default(none) private(i) shared(p) for (i = 0; i < p.n; ++i) { DoSomething(p, i); } struct p { int n; 双*l; } #pragma omp parallel用于默认(无)私有(i)共享(p) 对于(i=0;i

我有这个
并行的
循环

struct p
{
    int n;
    double *l;
}

#pragma omp parallel for default(none) private(i) shared(p)
for (i = 0; i < p.n; ++i)
{
    DoSomething(p, i);
}
struct p
{
int n;
双*l;
}
#pragma omp parallel用于默认(无)私有(i)共享(p)
对于(i=0;i

现在,在
DoSomething()
内部,
p.n
可能会增加,因为
p.l
中添加了新元素。我想以并行方式处理这些元素。OpenMP手册规定,
parallel for
不能与列表一起使用,因此
DoSomething()
将这些
p.l
的新元素添加到另一个列表中,该列表按顺序处理,然后与
p.l
合并。我不喜欢这种变通办法。有人知道更干净的方法吗?

OpenMP 3.0中添加了一个支持动态执行的结构,它就是
任务
结构。任务被添加到队列中,然后尽可能并发地执行。示例代码如下所示:

#pragma omp parallel private(i)
{
    #pragma omp single
    for (i = 0; i < p.n; ++i)
    {
       #pragma omp task
       DoSomething(p, i);
    }
}
#pragma omp single
{
   i = 0;
   while (i < p.n)
   {
      for (; i < p.n; ++i)
      {
         #pragma omp task
         DoSomething(p, i);
      }
      #pragma omp taskwait
      #pragma omp flush
   }
}
taskwait
构造使线程等待所有排队的任务执行。如果将新元素添加到列表中,则
while
的条件将再次变为真,并将发生新一轮任务创建。
flush
结构用于同步线程之间的内存视图,例如,使用共享存储器中的值更新优化寄存器变量


OpenMP 3.0受到所有现代C编译器的支持,但MSVC除外,它仍停留在OpenMP 2.0上。

在不知道会有多少个作业的情况下,您如何期望OpenMP生成作业?如果元素不存在,作业应该如何在该元素上工作?这是不可能的。当所有作业完成后,再次检查条件,如果有新的元素产生,开始更多的作业。这是值得一试的。我会尝试一下,因为你的答案最接近我需要的东西。我不需要一个#pragma omp parallel吗?第二个代码示例只展示了内部
单个
构造。您仍然需要外部
并行
区域。我接受您的回答,因为任务是我需要的,但我也需要相应地调整代码。如果p.n是300000(有时也可能是300000),我无法生成300k线程。OpenMP任务不是线程。它们是在任务池中排队的代码片段(比如回调),然后由并行区域的线程团队执行。但是你需要调整你的代码还有另一个原因——如果每次计算都相对便宜,那么任务开销可能会很大。在这种情况下,更明智的做法是为每个任务提供一个点数范围,并调整范围大小,以获得最佳性能。