OpenMP 有序子句

Suz*_*nka 6 c parallel-processing loops for-loop openmp

OpenMP 中的ordered 子句应该如何正确使用?有这个测试代码来检查循环是否会通过增加 n 的值来执行,但情况并非总是如此。

我是否误解了有序子句的定义?

有序结构指定循环区域中的结构化块,该块将按循环迭代的顺序执行。这对有序区域内的代码进行排序和排序,同时允许区域外的代码并行运行。

    #include <stdio.h>
    #include <stdlib.h>
    #include <omp.h>

    int main(){

        int n;
    omp_set_num_threads(4);
    #pragma omp parallel
        {
    #pragma omp for ordered
            for (n=0;n<10;n++)
                printf("n = %d\n",n);
        }
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

编译时

   gcc -Wall -Wextra -fopenmp test_par.c
Run Code Online (Sandbox Code Playgroud)

输出是

    ./a.out 
    n = 0 
    n = 1 
    n = 2 
    n = 9 
    n = 3 
    n = 4 
    n = 5 
    n = 6 
    n = 7 
    n = 8 
Run Code Online (Sandbox Code Playgroud)

Gil*_*les 5

OpenMPordered子句应该在两个不同的阶段使用:

  1. 作为for指令的子句,指示一些可能的迭代顺序;进而
  2. 作为一个独立指令,指示循环内语句的哪些部分要保持有序。

所以本质上,你的例子应该是:

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int main(){

    int n;
    omp_set_num_threads(4);
    #pragma omp parallel
    {
        #pragma omp for ordered
        for (n=0;n<10;n++)
            #pragma omp ordered
            printf("n = %d\n",n);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这使:

$ g++ -fopenmp order.cc
$ ./a.out 
n = 0
n = 1
n = 2
n = 3
n = 4
n = 5
n = 6
n = 7
n = 8
n = 9
Run Code Online (Sandbox Code Playgroud)

但是,这里有两点说明:

  1. 这个并行循环实际上是完全顺序化的,因为ordered指令之外没有任何东西
  2. 此外,如果您想减轻由ordered指令引起的序列化的影响,您应该使用该schedule指令。例如,在有序循环的情况下,“有效”调度的一个很好的候选者将是schedule( static, 1 )

最后,Hristo Iliev 比我在这里解释得更好