我可以将多个有序语句放入一个有序 for 循环 (OpenMP) 中吗?

标签 c gcc openmp undefined-behavior icc

我刚刚发现,虽然这个C代码给出了一个有序的整数列表(如预期的那样):

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

int main() {
#pragma omp parallel for ordered schedule(dynamic)
  for (int i=0; i<10; i++) {
#pragma omp ordered
    {
    printf("%i             (tid=%i)\n",i,omp_get_thread_num(); fflush(stdout);
    }
  }
}

对于 gcc 和 icc,以下行为会产生不良行为:

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

int main() {
#pragma omp parallel for ordered schedule(dynamic)
  for (int i=0; i<10; i++) {
#pragma omp ordered
    {
    printf("%i             (tid=%i)\n",i,omp_get_thread_num()); fflush(stdout);
    }

    usleep(100*omp_get_thread_num());
    printf("WORK IS DONE  (tid=%i)\n",omp_get_thread_num()); fflush(stdout);
    usleep(100*omp_get_thread_num());

#pragma omp ordered
    {
    printf("  %i           (tid=%i)\n",i,omp_get_thread_num()); fflush(stdout);
    }
  }
} 

我希望看到的是:
0
1
2
3
4
5
6
7
8
9
工作完成
工作完成
工作完成
工作完成
工作完成
工作完成
工作完成
工作完成
工作完成
工作完成
0
1
2
3
4
5
6
7
8
9

但是使用 gcc 则得到:
0 (tid=5)
工作完成 (tid=5)
0 (tid=5)
1 (tid=2)
工作完成 (tid=2)
1 (tid=2)
2 (tid=0)
工作完成 (tid=0)
2 (tid=0)
3 (tid=6)
工作完成 (tid=6)
3 (tid=6)
4 (tid=7)
工作完成 (tid=7)
4 (tid=7)
5 (tid=3)
工作完成 (tid=3)
5 (tid=3)
6 (tid=4)
工作完成 (tid=4)
6 (tid=4)
7 (tid=1)
工作完成 (tid=1)
7 (tid=1)
8 (tid=5)
工作完成 (tid=5)
8 (tid=5)
9 (tid=2)
工作完成 (tid=2)
9 (tid=2)
(所以一切都是有序的 - 甚至是可并行工作部分)

还有icc:
1 (tid=0)
2 (tid=5)
3 (tid=1)
4 (tid=2)
工作完成 (tid=1)
工作完成 (tid=3)
3 (tid=1)
6 (tid=4)
7 (tid=7)
8 (tid=1)
工作完成 (tid=0)
5 (tid=6)
工作完成 (tid=2)
1 (tid=0)
9 (tid=0)
工作完成 (tid=0)
工作完成 (tid=5)
工作完成 (tid=1)
9 (tid=0)
0 (tid=3)
8 (tid=1)
工作完成 (tid=4)
工作完成 (tid=6)
2 (tid=5)
工作完成 (tid=7)
6 (tid=4)
5 (tid=6)
4 (tid=2)
7 (tid=7)
(所以没有任何东西被排序,甚至是排序的子句)

在一个有序循环中使用多个有序子句是未定义的行为还是这里发生了什么?在我能找到的任何 OpenMP 文档中,我找不到任何禁止每个循环使用多个子句的内容。

我知道在这个简单的例子中我可以像这样分开循环

int main() {  
  for (int i=0; i<10; i++) {  
    printf("%i             (tid=%i)\n",i,omp_get_thread_num()); fflush(stdout);  
  }  
#pragma omp parallel for schedule(dynamic)  
  for (int i=0; i<10; i++) {  
    usleep(100*omp_get_thread_num());  
    printf("WORK IS DONE  (tid=%i)\n",omp_get_thread_num()); fflush(stdout);  
    usleep(100*omp_get_thread_num());  
  }  
  for (int i=0; i<10; i++) {  
    printf("  %i           (tid=%i)\n",i,omp_get_thread_num()); fflush(stdout);  
  }          
}  

所以我不是在寻找解决方法。我真的很想了解这里发生了什么,这样我就可以处理真实的情况,而不会遇到任何破坏性/意外的事情。

我真的希望你能帮助我。

最佳答案

根据OpenMP 4.0 API specifications你不能。

Only one ordered clause can appear on a loop directive (p. 58)

关于我可以将多个有序语句放入一个有序 for 循环 (OpenMP) 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31043724/

相关文章:

c - 带有字符串的结构,包括适当的内存管理

c++ - 转发声明文件 *

parallel-processing - FORTRAN 中的 OpenMP 未运行预期的线程数

c - GCC 热补丁?

c - gcc:修复 -pedantic "unnamed structure"警告

c - 使用 open mp 的慢速稀疏矩阵 vector 积 (CSR)

C 和 OpenMP : pointer to shared read-only data slows down execution

C : How to make the size of an array dynamic?

c++ - 获取Windows版本的正确方法

c - 如何在没有嵌套循环的情况下实现三项式展开。