GCC OpenMP任务无法工作。

5

我已经使用了带有“pragma omp for”循环的OpenMP,并想尝试使用OpenMP任务。 但是一个应该并行运行2个任务的简单程序似乎不能正常工作。 我是否误解了任务的用法,或者这里有什么问题?

#include<iostream>
#include<omp.h>

//ubuntu 12.04 LTS, gcc 4.6.3
//g++ test_omp.cpp -fopenmp

int main()
{
 #pragma omp parallel
 {
  #pragma omp single
  {

      #pragma omp task
      {
          while(true) 
          {
           usleep(1e6);
           #pragma omp critical (c_out)
            std::cout<<"task1"<<std::endl;
          }
      }

      #pragma omp task
      {
          while(true) 
          {
           usleep(1e6);
           #pragma omp critical (c_out)
            std::cout<<"task2"<<std::endl;
          }
      }

  }
 }
}

输出结果为: 任务1 任务1 任务1 .....
因此第二个任务没有运行。
1个回答

3
根据OpenMP规范:
当一个线程遇到任务构造时,从相关结构化块的代码生成一个任务。任务的数据环境根据任务构造上的数据共享属性子句、每个数据环境ICV和应用的任何默认值来创建。
遇到任务构造的线程可以立即执行任务,也可以推迟执行。在后一种情况下,团队中的任何线程都可以被分配任务。可以使用任务同步构造来保证任务的完成。任务构造可以嵌套在外部任务中,但内部任务的任务区域不是外部任务的一部分。
(强调是我的)
我的理解是:单个线程开始执行您的单个部分。它到达任务指令,此时它可以决定自己运行任务还是将其交给另一个线程。当它决定自己运行任务时,问题就出现了 - 它永远不会返回。
不过,我不太确定您为什么在示例中使用“任务”/“单个”。您想要执行的操作似乎更适合使用“omp parallel sections”:
int main()
{
 #pragma omp parallel sections num_threads(2)
 {
      #pragma omp section
      {
          while(true)
          {
           usleep(3e5);
           #pragma omp critical (c_out)
            std::cout<<"task1"<<std::endl;
          }
      }
      #pragma omp section
      {
          while(true)
          {
           usleep(5e5);
           #pragma omp critical (c_out)
            std::cout<<"task2"<<std::endl;
          }
      }
 }
}

我曾认为OpenMP任务总是一种“生成”或“分叉”,遇到此任务的线程会继续工作。但我错了。 - martin7743

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接