Ответ 1
OMP_NUM_THREADS
и omp_set_num_threads()
не эквивалентны. Переменная окружения используется только для установки начального значения nthreads-var ICV (переменная внутреннего контроля), которая контролирует максимальное количество потоков в команде. omp_set_num_threads()
может использоваться для изменения значения nthreads-var в любое время (конечно, вне каких-либо параллельных областей) и влияет на все последующие параллельные области. Поэтому установка значения, например, n
, OMP_NUM_THREADS
эквивалентно вызову omp_set_num_threads(n)
до того, как будет обнаружена самая первая параллельная область.
Алгоритм определения количества потоков в параллельной области очень четко описан в спецификации OpenMP, которая свободно доступна на веб-сайте OpenMP:
if a
num_threads
clause existsзатем пусть ThreadsRequested будет значением выражения предложения
num_threads
;else let ThreadsRequested = значение первого элемента nthreads-var;
Этот приоритет различных способов установки nthreads-var указан в части спецификации ICV Override Relationships:
Предложение
num_threads
иomp_set_num_threads()
переопределяют значение переменной средыOMP_NUM_THREADS
и начальное значение первого элемента ICV nthreads-var.
В переводе на человеческий язык, то есть:
OMP_NUM_THREADS
(если присутствует) первоначально определяет количество потоков;- вызовы
omp_set_num_threads()
переопределяют значениеOMP_NUM_THREADS
; - Наличие предложения
num_threads
переопределяет оба других значения.
На фактическое количество используемых потоков также влияет то, включены ли динамические размеры команды (dyn-var ICV устанавливается через OMP_DYNAMIC
и/или omp_set_dynamic()
), и зависит от того, накладывается ли ограничение потока с помощью thread-limit-var (устанавливается через OMP_THREAD_LIMIT
), а также от того, включен ли вложенный параллелизм (OMP_NESTED
/omp_set_nested()
) или нет.