Переопределение OMP_NUM_THREADS из кода - по-настоящему - PullRequest
2 голосов
/ 29 мая 2019

Все ответы, которые я смог найти до сих пор, предлагают позвонить omp_set_num_threads.Хотя это правильный ответ для большинства случаев, он не работает для меня.Внутренне, вызов omp_set_num_threads вызывает создание ICV для каждого потока (или модификацию, если текущий поток уже имеет один), и количество потоков сохраняется там.Это означает, что если есть другой поток, который запускает параллельную область, он не увидит наше новое значение.Так что вызов omp_set_num_threads! = Установка переменной env OMP_NUM_THREADS.

Есть ли способ изменить глобальный ICV?

Примечание: зачем мне это делать: я работаю с библиотекойрабочий поток для меня, поэтому я не контролирую его жизненный цикл.

Простейший пример для воспроизведения:

export OMP_NUM_THREADS=3

#include <omp.h>
#include <iostream>
#include <thread>

void job() {
  #pragma omp parallel
  {
    if (omp_get_thread_num() == 0) {
      std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
    }
  };
}


int main () {
  omp_set_num_threads(2);
  #pragma omp parallel
  {
    if (omp_get_thread_num() == 0) {
      std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
    }
  };
  std::thread t(job);
  t.join();
}

Это производит

Num threads:2
Num threads:3

Ответы [ 2 ]

1 голос
/ 29 мая 2019

Проблема с тем, чего вы пытаетесь достичь, находится за пределами спецификации OpenMP. OpenMP предполагает, что это единственная модель программирования в процессе приложения, и поэтому он знает что-либо о том, что происходит, когда вы создаете новый поток, который также выполняет код OpenMP.

В частности, для вашей проблемы: ICV num-threads является ICV для частного потока, это означает, что вызов omp_set_num_threads() влияет только на ICV, хранящийся в потоке, который вызывает omp_set_num_threads().

Итак, новый std::thread получит новую копию, инициализированную из переменной envionment. Вы не сможете изменить его из основного потока, который породил новый поток.

0 голосов
/ 29 мая 2019

Переопределение OMP_NUM_THREADS из кода ...

Измените это:

int main () {
  omp_set_num_threads(2);
  #pragma omp parallel
  {
    if (omp_get_thread_num() == 0) {
      std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
    }
  };
  std::thread t(job);
  t.join();
}

на это:

int main () {
  #pragma omp parallel num_threads(2)
  {
    if (omp_get_thread_num() == 0) {
      std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
    }
  };
  std::thread t(job);
  t.join();
}

Я считаю, что работаетс компиляторами Microsoft, которые застряли где-то в 2003 году для OpenMP.Выпуск 2003 OpenMP приблизительно равен версии 2.0 или 2.1, если я правильно помню.

См. Также Разница между num_threads и omp_set_num_threads по сравнению с OMP_NUM_THREADS .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...