【问题标题】:OpenMP ordered clauseOpenMP 有序子句
【发布时间】:2015-11-27 12:37:25
【问题描述】:

如何正确使用 OpenMP 中的有序子句?有这个测试代码来检查循环是否会通过增加 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;
    }

编译时使用

   gcc -Wall -Wextra -fopenmp test_par.c

输出是

    ./a.out 
    n = 0 
    n = 1 
    n = 2 
    n = 9 
    n = 3 
    n = 4 
    n = 5 
    n = 6 
    n = 7 
    n = 8 

【问题讨论】:

    标签: c loops for-loop parallel-processing openmp


    【解决方案1】:

    OpenMP ordered 子句应该用于两个不同的阶段:

    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;
    }
    

    这给出了:

    $ 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
    

    但是,这里有两点说明:

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

    最后,Hristo Iliev 对这一切的解释比我能用here 更好地解释了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-13
      • 2015-04-13
      • 2012-04-26
      • 2013-04-22
      • 1970-01-01
      • 2018-01-30
      • 2013-02-24
      • 1970-01-01
      相关资源
      最近更新 更多