#c #c #multithreading #openmp #openmpi
#c #c #многопоточность #openmp #openmpi
Вопрос:
Я работаю над программой как с OpenMP, так и с OpenMPI.
Для процесса, запущенного на начальном узле, я бы хотел, чтобы один поток работал как планировщик (взаимодействовал с другими узлами), а другие выполняли вычисления.
Структура кода выглядит так:
int computation(...)
{
#pragma parallel for .....
}
int main(...)
{
...
if (mpi_rank == 0) // initial node
{
#pragma omp parallel
{
#pragma omp master
{
// task scheduling for other nodes
}
{
// WRONG: said 4 threads in total, this block will be executed for
// 3 times simultaneously, and the nested "for" in the function
// will spawn 4 threads each as well
// so ACTUALLY 3*4 1=13 threads here!
int computation(...);
}
}
}
else // other nodes
{
// get a task from node 0 scheduler by MPI
int computation(...);
}
}
Я хочу, чтобы в начальном узле планировщик выполнял один поток, и одновременно выполнялась только одна вычислительная функция, поэтому одновременно используется не более 4 потоков.
Я тоже пробовал:
int computation(...)
{
register int thread_use = omp_get_max_threads(); // this is 4
if (rank == 0)
{
--thread_use; // if initial node, use 3
}
#pragma parallel for ..... num_threads(thread_use)
}
int main(...)
{
...
if (mpi_rank == 0) // initial node
{
#pragma omp parallel
{
#pragma omp master
{
// task scheduling for other nodes
}
#pragma omp single
{
// WRONG: nest "for" can only use 1 thread
int computation(...);
}
}
}
else // other nodes
{
// get a task from node 0 scheduler by MPI
int computation(...);
}
}
…или
//other parts are the same as above
if (mpi_rank == 0) // initial node
{
#pragma omp parallel num_threads(2)
{
#pragma omp master
{
// task scheduling for other nodes
}
{
// WRONG: nest "for" can only use 1 thread
int computation(...);
}
}
}
…но ни один из них не работал.
Как я должен упорядочить блоки с помощью OpenMP для достижения моей цели? Любая помощь будет оценена, большое спасибо.
Ответ №1:
Прежде всего, если вы хотите указать вложенный параллелизм в OpenMP, вам необходимо установить переменную окружения OMP_NESTED
на true
.
Тогда возможная реализация может выглядеть следующим образом:
// Parallel region. Topmost level
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
scheduling_function();
#pragma omp section
compute_function();
}
Где scheduling_function()
находится однопоточная функция, а compute_function()
структура похожа на:
void compute_function() {
// Nested parallel region. Bottommost level
#pragma omp parallel
{
computation();
}
}
Дополнительная информация о вложенном параллелизме OpenMP
Комментарии:
1. Потрясающе! Большое спасибо.
2. Примите во внимание, что вы также можете установить количество потоков, используемых на каждом уровне вложенности, со значениями, разделенными запятыми, в
OMP_NUM_THREADS
переменной среды.