首页 > 解决方案 > 有没有办法摆脱#omp并行

问题描述

我有一种情况,我在一个块中有两个#pragma omp tasks#pragma omp parallel

第一项任务很简单,只需等待 5 秒。第二个任务更困难的是等待复杂的用户输入动作。

bool timed_out=false;
#pragma omp parallel num_threads(2), shared(timed_out)
{
  #pragma omp task
  {
    sleep(5);
    #pragma omp atomic write
    time_out=true;
  }
  #pragma omp task
  {
    // wait for user input
  }
  #pragma omp taskwait
}

基本上,我希望在成功接收到用户输入或 5 秒超时后发生什么,然后我想跳出该#pragma omp parallel部分并继续 main。

我认为我不能#pragma omp single在我的 taskwait 之后使用,因为如果收到用户输入,接下来会发生两个工作线程的生成。

标签: c++openmp

解决方案


请注意,您的初始示例不会生成两个任务,而是生成四个任务,因为并行区域中的两个 OpenMP 线程中的每一个都会遇到该task构造并因此创建一个任务。您必须task用 a masterorsingle构造包装这两个构造以避免这种情况并确保只有一个任务创建任务:

bool timed_out=false;
#pragma omp parallel num_threads(2), shared(timed_out)
{
  #pragma omp master
  {
    #pragma omp task
    {
      sleep(5);
      #pragma omp atomic write
      time_out=true;
    }
    #pragma omp task
    {
      // wait for user input
    }
    #pragma omp taskwait
  }
}

对于等待的第二个任务的终止,您可以使用 OpenMP 取消:

bool timed_out=false;
#pragma omp parallel master num_threads(2), shared(timed_out)
{
  #pragma omp taskgroup
  {
    #pragma omp task
    {
      sleep(5);
      #pragma omp atomic write
      time_out=true;
      #pragma omp cancel taskgroup
    }
    #pragma omp task
    {
      while(true) {
        #pragma omp taskyield
        #pragma omp cancellation point taskgroup
      }
    }
    #pragma omp taskwait
}

taskgroup需要定义应受cancel构造影响的任务。一旦遇到构造,等待任务中的cancellation point构造将终止while循环。cancel由于第二个任务正在旋转等待,它包含一个taskyield用于引入任务调度点并允许 OpenMP 实现调度另一个任务(这对于您的最小示例来说不需要,但对于具有更多 OpenMP 任务的代码可能很有用)。


推荐阅读