Внутри параллельной области OpenMP все потоки выполняют один и тот же код (как в MPI), и работа разделяется только тогда, когда потоки достигают цикла/раздела/задачи.
В вашем примере работа внутри циклов (OMP DO
) распределяется между доступными потоками. После завершения цикла неявный барьер синхронизирует все потоки, а затем они параллельно выполняют функцию DGTSV
. После возврата подпрограммы цикл снова разделяется.
@HristoIliev предложил использовать пункт OMP SINGLE
. Это ограничивает выполнение фрагмента кода внутри только одним потоком и заставляет все остальные потоки ждать его (если вы не укажете nowait
).
С другой стороны, вложенный параллелизм вызывается в том случае, когда вы объявляете параллельную область внутри другой параллельной области. Это также применимо, когда вы выполняете вызовы параллельной библиотеки OpenMP внутри параллельного региона.
По умолчанию OpenMP не увеличивает параллелизм вложенных параллельных областей, вместо этого его может выполнить только поток, который входит в параллельную область. Это поведение можно изменить с помощью переменной среды с OMP_NESTED
по true
.
Решение OMP SINGLE
намного лучше, чем разделение параллельной области на две части, так как ресурсы повторно используются для следующего цикла:
$!OMP PARALLEL
$!OMP DO
DO ...
END DO
$!OMP SINGLE
CALL DGTSV(...)
$!OMP DO
DO ...
END DO
$!OMP END PARALLEL
Чтобы проиллюстрировать использование OMP_NESTED
, я покажу вам некоторые результаты, которые я получил от приложения, которое использовало FFTW (реализация быстрого преобразования Фурье), сконфигурированное для использования OpenMP. Выполнение выполнялось на 16-ядерном двухпроцессорном узле Intel Xeon E5 @2,46 ГГц.
На следующих графиках показано количество времени, затрачиваемое на все приложение, где параллельные регионы появляются, когда ЦП > 1, сериализованные регионы, когда ЦП = 1, и регионы синхронизации, когда ЦП = 0.
Приложение смущающе параллельно, поэтому в данном конкретном случае использование вложенности нецелесообразно (FFTW не так хорошо масштабируется).
Это исполнение OMP_NESTED=false
. Обратите внимание, как количество параллелизма ограничено количеством потоков, потраченных во внешней параллельной области (ftdock).
![Невложенная версия OpenMP](https://i.stack.imgur.com/eyZWq.png)
Это OMP_NESTED=true
казнь. В этом случае можно увеличить параллелизм дальше, чем количество потоков, затраченных на внешнюю параллельную область. Максимально возможный параллелизм в этом случае равен 16, когда либо 8 внешних потоков создают один узел для выполнения внутренней параллельной области, либо 4 создают по 3 дополнительных потока каждый (8x2 = 4x4 = 16).
![Вложенная версия OpenMP](https://i.stack.imgur.com/nebMd.png)
person
Jorge Bellon
schedule
06.10.2016
DGTSV
вне параллельного региона, и он создаст свой собственный параллельный регион внутри реализации подпрограммы. - person Hristo Iliev   schedule 24.07.2012DGTSV
внутрь конструкции OpenMPSINGLE
и включить вложенный параллелизм. Это сэкономит вам крошечную долю времени. - person Hristo Iliev   schedule 25.07.2012