Поток OpenMP, управляющий циклами - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь оптимизировать использование потока в комплексе для l oop с OpenMP. Код basi c выглядит следующим образом:

for (...) //loop1
{
  #pragma omp parallel
  {
    #pragma omp single
    {
      //section that needs to be executed only once
    }

    #pragma omp for
    {
      for (...) //loop2
      {
        ...
      }
    }

    #pragma omp single
    {
      //section that needs to be executed only once
    }

    #pragma omp for
    {
      for (...) //loop3
      {
        ...
      }
    }
    ...
  }
}

Моя проблема связана с созданием / уничтожением потоков, так как этот код подразумевает, что каждая итерация создает и уничтожает N потоков. Есть ли способ указать среде выполнения повторно использовать те же потоки (что-то вроде пула потоков), или это что-то оставлено для реализации?

Мне нужно обратить внимание на эти ограничения:

  • Содержимое loop1 можно (и нужно) сделать параллельным, поскольку оно содержит некоторые довольно сложные научные c вычисления
  • Итерации loop1 должны быть упорядочено, поэтому само l oop нельзя сделать параллельным

EDIT Каждая итерация цикла loop1 должна выполняться только один раз (поэтому я могу не делайте всю l oop параллельной

1 Ответ

0 голосов
/ 28 февраля 2020

Во-первых, потоки не будут создаваться / уничтожаться на каждой итерации loop1. Обычно существует политика ожидания потока, которой вы можете управлять с помощью переменной окружения OMP_WAITY_POLICY:

https://www.openmp.org/spec-html/5.0/openmpse55.html#x294 -20640006.7

Кроме того, ничего не происходит (в хотя бы в вашем псевдокоде), мешающем обернуть весь код в один параллельный регион Код вполне может быть:

#pragma omp parallel
for (...) //loop1
{
  #pragma omp single
  {
    //section that needs to be executed only once
  }

  #pragma omp for
  for (...) //loop2
  {
    ...
  }

  #pragma omp single
  {
    //section that needs to be executed only once
  }

  #pragma omp for
  for (...) //loop3
  {
    ...
  }
  ...
}

Неявные барьеры в конце каждой конструкции совместного использования (ie, первый сингл, loop2, второй сингл и loop) гарантируют порядок между итерациями. В случае, если эти барьеры не нужны, вы можете избежать их, используя предложение nowait.

...