Нет проблем с запуском параллельной секции в другой подпрограмме до for, конечно, начиная с OpenMP 3.0 (2008) и, возможно, начиная с OpenMP 2.5. С gcc4.4:
outer.c:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void update(int n, int iter);
int main(int argc, char **argv) {
int n=10;
#pragma omp parallel num_threads(4) default(none) shared(n)
for (int iter=0; iter<3; iter++)
{
#pragma omp single
printf("---iteration %d---\n", iter);
update(n, iter);
}
return 0;
}
inner.c:
#include <omp.h>
#include <stdio.h>
void update(int n, int iter) {
int thread = omp_get_thread_num();
#pragma omp for
for (int i=0;i<n;i++) {
int newthread=omp_get_thread_num();
printf("%3d: doing loop index %d.\n",newthread,i);
}
}
Строительство:
$ make
gcc44 -g -fopenmp -std=c99 -c -o inner.o inner.c
gcc44 -g -fopenmp -std=c99 -c -o outer.o outer.c
gcc44 -o main outer.o inner.o -fopenmp -lgomp
$ ./main
---iteration 0---
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
3: doing loop index 9.
---iteration 1---
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
3: doing loop index 9.
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
---iteration 2---
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
3: doing loop index 9.
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
Но в соответствии с @ jdv-Jan de Vaan, я был бы очень удивлен, если бы в современной имплементации OpenMP это привело к значительному улучшению производительности по сравнению с параллелью для в обновлении, особенно если обновление достаточно дорогое. ,
Кстати, есть проблемы с установкой параллели вокруг i-цикла в процедуре Гаусса-Зейделя в обновлении; Вы можете видеть, что шаги i не являются независимыми, и это приведет к условиям гонки. Вместо этого вам нужно будет сделать что-то вроде красно-черного или якоби ...
Обновление:
Пример кода предоставлен для итерации G-S, а не для Якоби, но я просто предположу, что это опечатка.
Если ваш вопрос на самом деле касается цикла сокращения, а не осиротевшего цикла for: да, вам, к сожалению, приходится бросать свои собственные минимальные / максимальные сокращения в OpenMP, но это довольно просто, вы просто используете обычные приемы.
Обновление 2 - yikes, locmax должен быть приватным, а не общим.
outer.c:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int update(int n, int iter);
int main(int argc, char **argv) {
int n=10;
int max, locmax;
max = -999;
#pragma omp parallel num_threads(4) default(none) shared(n, max) private(locmax)
for (int iter=0; iter<3; iter++)
{
#pragma omp single
printf("---iteration %d---\n", iter);
locmax = update(n, iter);
#pragma omp critical
{
if (locmax > max) max=locmax;
}
#pragma omp barrier
#pragma omp flush
#pragma omp single
printf("---iteration %d's max value = %d---\n", iter, max);
}
return 0;
}
inner.c:
#include <omp.h>
#include <stdio.h>
int update(int n, int iter) {
int thread = omp_get_thread_num();
int max = -999;
#pragma omp for
for (int i=0;i<n;i++) {
printf("%3d: doing loop index %d.\n",thread,i);
if (i+iter>max) max = i+iter;
}
return max;
}
и здание:
$ make
gcc44 -g -fopenmp -std=c99 -c -o inner.o inner.c
gcc44 -g -fopenmp -std=c99 -c -o outer.o outer.c
gcc44 -o main outer.o inner.o -fopenmp -lgomp
bash-3.2$ ./main
---iteration 0---
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
3: doing loop index 9.
---iteration 0's max value = 9---
---iteration 1---
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
3: doing loop index 9.
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
---iteration 1's max value = 10---
---iteration 2---
0: doing loop index 0.
0: doing loop index 1.
0: doing loop index 2.
1: doing loop index 3.
1: doing loop index 4.
1: doing loop index 5.
3: doing loop index 9.
2: doing loop index 6.
2: doing loop index 7.
2: doing loop index 8.
---iteration 2's max value = 11---