У меня есть 4 темы, и я хочу запустить одновременно 3 функции. Каждая функция занимает один поток.
Но этот код запускается каждую функцию 4 раза
#pragma omp parallel
{
Func1();
Func2();
Func3();
}
и у меня есть такой результат:
Func *1* началось
Func *1* началось
Func *1* началось
Func *1* началось
Func *1* закончено
Func *1* закончено
Func *1* закончено
Func *1* закончено
Func *2* началось
Func *2* началось
Func *2* началось
Func *2* началось
Func *2* закончено
Func *2* закончено
Func *2* закончено
Func *2* закончено
…
Как я должен изменить код для отображения примерно так:
Func *1* началось
Func *2* началось
Func *3* началось
Func *2* закончено
Func *1* закончено
Func *3* закончено
То, что вы ищете, это sections
конструктивная конструкция. Синтаксис должен быть следующим:
#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
Func1();
#pragma omp section
Func2();
#pragma omp section
Func3();
}
}
Я предлагаю вам обратиться к технические характеристики и примеры там для получения дополнительной информации о том, как работает эта конструкция.
Как уже ответил Массимилиано, самый простой способ достичь того, что вы хотите, это использовать sections
построить:
#pragma omp parallel sections
{
#pragma omp section
Func1();
#pragma omp section
Func2();
#pragma omp section
Func3();
}
(когда sections
конструкция является единственным вложенным в parallel
регион, обе прагмы могут быть объединены, как показано)
каждый section
определяет оператор или блок, следующий сразу за ним. Например. если вы хотите добавить еще какой-то код в раздел, вы должны поместить его в блок:
#pragma omp section
{
Func1();
SomeOtherFunc1();
}
Более общий способ управления тем, что делает каждый поток, состоит в проверке идентификатора потока, возвращаемого omp_get_thread_num()
и разветвляться в соответствии. Это похоже на способ написания MPI-программ:
#pragma omp parallel
{
switch (omp_get_thread_num())
{
case 0:
Func1();
break;
case 1:
Func2();
break;
case 2:
Func3();
break;
default:
// Do nothing
}
}
Один очевидный недостаток состоит в том, что он будет работать только в том случае, если в команде, выполняющей параллельную область, будет хотя бы 3 потока, то есть код, основанный на идентификаторах потоков, станет несколько непереносимым. В отличие от sections
директива работает с любым количеством потоков, например если есть только один поток, все разделы будут выполняться последовательно.