Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc openmp tasks do not work

Tags:

gcc

task

openmp

I have already used OpenMP with "pragma omp for" loops and wanted to try OpenMP tasks now. But a simple program, which should run 2 tasks parallel does not seem to work. Did I misunderstand the use of tasks or what is wrong here?

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

  }
 }
}

The output is: task1 task1 task1 .....

So the second task is not running.

like image 873
martin7743 Avatar asked Oct 21 '22 23:10

martin7743


1 Answers

From the OpenMP spec:

When a thread encounters a task construct, a task is generated from the code for the associated structured block. The data environment of the task is created according to the data-sharing attribute clauses on the task construct, per-data environment ICVs, and any defaults that apply.

The encountering thread may immediately execute the task, or defer its execution. In the latter case, any thread in the team may be assigned the task. Completion of the task can be guaranteed using task synchronization constructs. A task construct may be nested inside an outer task, but the task region of the inner task is not a part of the task region of the outer task.

(emphasis mine)

The way I read this: A single thread starts executing your single section. It reaches the task directive, at which point it may decide to either run the task itself, or give it to another thread. The problem occurs when it decides to run the task itself - it never returns.

I'm not quite sure why you have task/single in your example though. What you want to do seems like a case for omp parallel sections instead:

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;
          }
      }
 }
}
like image 150
us2012 Avatar answered Jan 02 '23 21:01

us2012