Это можно сделать! Ключевым моментом здесь является перемещение цикла внутри одной параллельной секции и проверка того, что все, что используется для определения повторения или нет, все потоки примут абсолютно одинаковое решение. Я использовал общие переменные и выполняю синхронизацию непосредственно перед проверкой условия цикла.
Итак, этот код:
initialize();
while (some_condition) {
#pragma omp parallel
{
some_parallel_work();
}
}
можно преобразовать во что-то вроде этого:
#pragma omp parallel
{
#pragma omp single
{
initialize(); //if initialization cannot be parallelized
}
while (some_condition_using_shared_variable) {
some_parallel_work();
update_some_condition_using_shared_variable();
#pragma omp flush
}
}
Самое главное - быть уверенным, что каждый поток принимает одно и то же решение в одних и тех же точках вашего кода.
Как заключительная мысль, по сути, то, что человек делает, это тратит накладные расходы на создание / уничтожение потоков (каждый раз, когда раздел #pragma omp parallel начинается / заканчивается) на накладные расходы на синхронизацию для принятия решений потоками. Я думаю, что синхронизация должна быть быстрее, однако здесь есть несколько параметров, которые могут быть не всегда.