Один уровень распараллеливания почти всегда лучший, т. Е. Пример 1: первый параллельный цикл.
Пример 2 фактически будет делать то же, что и пример 1 (второй оператор #pragma omp parallel
for игнорируется, поскольку вложенное распараллеливание отключено).
Пример 3, скорее всего, плохая идея. Затраты на порождение новых потоков возникают на каждой итерации из цикла 1. Случаи, когда было бы лучше распараллеливать только первый цикл (или только второй цикл), нетривиальны. Не гарантируется, что он будет поддерживаться всеми компиляторами (некоторые могут игнорировать вложенную часть).
Пример 4 - это другой вариант, когда распараллеливание самого внешнего цикла не может быть выполнено по какой-либо причине (например, использование памяти), но мы хотим порождать потоки только один раз и повторно использовать их на каждой итерации самого внешнего петля. Некоторые издержки синхронизации будут возникать на каждой итерации, но намного меньше, чем стоило бы многократное создание потоков.
// EXAMPLE - SECOND LOOP PARALLEL
#pragma omp parallel
for (;;) {
// DO SOMETHING EVERY THREAD SHOULD DO
// e.g. declare local variables, increment private counter...
#pragma omp single
{
// DO SOMETHING ONCE ONLY
// e.g. read data from a file, initialize a shared variable
}
#pragma omp for
for(;;) {
// DO SOMETHING
}
}