omp ordered子句如何工作?

时间:2012-11-04 23:41:52

标签: c++ parallel-processing openmp

vector<int> v;

#pragma omp parallel for ordered schedule(dynamic, anyChunkSizeGreaterThan1)
    for (int i = 0; i < n; ++i){
            ...
            ...
            ...
#pragma omp ordered
            v.push_back(i);
    }

这会使v填充n大小的有序列表。

当到达omp ordered块时,所有线程都需要等待最低迭代可能线程完成,但是如果没有任何线程被指定为特定迭代怎么办?或者OpenMP运行时库是否始终确保某个线程处理最低的迭代?

为什么建议将ordered子句与dynamic schedule一起使用? static schedule会影响效果吗?

1 个答案:

答案 0 :(得分:41)

ordered子句的工作原理如下:不同的线程并发执行,直到它们遇到ordered区域,然后按照与在串行循环中执行的顺序相同的顺序执行。这仍然允许一定程度的并发性,特别是如果ordered区域之外的代码部分具有大量运行时间。

没有特别的理由使用dynamic计划而不是static计划使用小块大小。这一切都取决于代码的结构。由于ordered引入了线程之间的依赖关系,如果与schedule(static)一起使用默认块大小,则第二个线程必须等待第一个线程完成所有迭代,然后第三个线程将不得不等待第二个完成迭代(因此也是第一个),依此类推。可以通过3个线程和9个迭代(每个线程3个)轻松地将其可视化:

tid  List of     Timeline
     iterations
0    0,1,2       ==o==o==o
1    3,4,5       ==.......o==o==o
2    6,7,8       ==..............o==o==o

=表明线程并行执行代码。 o是线程执行ordered区域的时间。 .是线程空闲,等待轮到执行ordered区域。使用schedule(static,1)会发生以下情况:

tid  List of     Timeline
     iterations
0    0,3,6       ==o==o==o
1    1,4,7       ==.o==o==o
2    2,5,8       ==..o==o==o

我认为两种情况的区别都是显而易见的。对于schedule(dynamic),上面的图片将或多或少随机,因为分配给每个线程的迭代列表是不确定的。它还会增加额外的开销。只有当每次迭代的计算量不同时才会有用,并且与使用动态调度的额外开销相比,它需要花费更多的时间来进行计算。

不要担心编号最小的迭代。它通常被处理到团队中的第一个线程,以准备好执行代码。