Есть ли способ вырваться из #omp parallel

#c #openmp

#c #openmp

Вопрос:

У меня ситуация, когда у меня есть два #pragma omp task s внутри #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 after my taskwait, потому что, если пользовательский ввод получен, следующее, что произойдет, — это создание двух рабочих потоков.

Ответ №1:

Пожалуйста, обратите внимание, что ваш первоначальный пример генерирует не две задачи, а четыре, поскольку каждый из двух потоков OpenMP в параллельной области столкнется с task конструкцией и, таким образом, создаст задачу. Вам нужно было бы обернуть две task конструкции с master single помощью конструкции or, чтобы избежать этого и убедиться, что только одна задача создает задачи:

 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 обнаружения конструкции. Поскольку вторая задача находится в режиме ожидания, она содержит a taskyield , чтобы ввести точку планирования задачи и разрешить реализации OpenMP планировать другую задачу (это не требуется для вашего минимального примера, но может быть полезно для кода с большим количеством задач OpenMP).

Комментарии:

1. Я только что осознал, что поменял роли задач, но я предполагаю, что точка все еще встречается.