openMP вложенная параллель для циклов против внутренней параллели для
Если я использую вложенную параллель для таких циклов:
#pragma omp parallel for schedule(dynamic,1)
for (int x = 0; x < x_max; ++x) {
#pragma omp parallel for schedule(dynamic,1)
for (int y = 0; y < y_max; ++y) {
//parallelize this code here
}
//IMPORTANT: no code in here
}
это эквивалентно:
for (int x = 0; x < x_max; ++x) {
#pragma omp parallel for schedule(dynamic,1)
for (int y = 0; y < y_max; ++y) {
//parallelize this code here
}
//IMPORTANT: no code in here
}
Является ли внешняя параллель для выполнения чего-либо другого, кроме создания новой задачи?
Ответы
Ответ 1
Если ваш компилятор поддерживает OpenMP 3.0, вы можете использовать предложение collapse
:
#pragma omp parallel for schedule(dynamic,1) collapse(2)
for (int x = 0; x < x_max; ++x) {
for (int y = 0; y < y_max; ++y) {
//parallelize this code here
}
//IMPORTANT: no code in here
}
Если это не так (например, поддерживается только OpenMP 2.5), существует простой способ:
#pragma omp parallel for schedule(dynamic,1)
for (int xy = 0; xy < x_max*y_max; ++xy) {
int x = xy / y_max;
int y = xy % y_max;
//parallelize this code here
}
Вы можете включить вложенный параллелизм с omp_set_nested(1);
и ваш вложенный omp parallel for
кода будет работать, но это может быть не лучшая идея.
Кстати, почему динамическое планирование? Является ли каждая итерация цикла оценена в непостоянное время?
Ответ 2
NO.
Первая #pragma omp parallel
создаст команду параллельных потоков, а вторая попытается создать для каждого из исходных потоков другую команду, то есть команду команд. Однако практически во всех существующих реализациях вторая команда имеет только один поток: вторая параллельная область по существу не используется. Таким образом, ваш код больше похож на
#pragma omp parallel for schedule(dynamic,1)
for (int x = 0; x < x_max; ++x) {
// only one x per thread
for (int y = 0; y < y_max; ++y) {
// code here: each thread loops all y
}
}
Если вы этого не хотите, но только параллельный внутренний цикл, вы можете сделать это:
#pragma omp parallel
for (int x = 0; x < x_max; ++x) {
// each thread loops over all x
#pragma omp for schedule(dynamic,1)
for (int y = 0; y < y_max; ++y) {
// code here, only one y per thread
}
}