OPM OPCERDERS子句如何起作用

How does the omp ordered clause work?

本文关键字:起作用 子句 OPCERDERS OPM      更新时间:2023-10-16
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);
    }

这将vn大小的订购列表填充。

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

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

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),由于分配给每个线程的迭代列表是非确定性的,因此上面的图片将变得或多或少随机。它还将增加开销。只有在每次迭代的计算量不同时才有用,并且进行计算需要更多的时间来使用动态调度。

不必担心编号最低的迭代。通常将其处理到团队中的第一个线程以准备执行代码。