См редактировать ниже моего предварительного решенияPrivate «для» петли для каждого потока в OpenMP
Рассмотрим следующий код:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main(void) {
int counter = 0;
int i;
omp_set_num_threads(8);
#pragma omp parallel
{
int id = omp_get_thread_num();
#pragma omp for private(i)
for (i = 0; i<10; i++) {
printf("id: %d thread: %d\n", i, id);
#pragma omp critical // or atomic
counter++;
}
}
printf("counter %d\n", counter);
return 0;
}
Я определяю количество нитей, чтобы быть 8. Для каждого из 8 потоков я хотел бы иметь цикл for
для каждого отдельного потока, который увеличивает значение переменной counter
. Тем не менее, кажется, что OpenMP распараллеливания for
цикл:
i: 0 thread: 0
i: 1 thread: 0
i: 4 thread: 2
i: 6 thread: 4
i: 2 thread: 1
i: 3 thread: 1
i: 7 thread: 5
i: 8 thread: 6
i: 5 thread: 3
i: 9 thread: 7
counter 10
Следовательно, counter=10
, но я хочу counter=80
. Что я могу сделать так, чтобы каждый поток выполнял свой собственный цикл for
, пока все потоки увеличивались counter
?
Следующий код дает желаемый результат: я добавил еще один внешний for
петлю, что петли от 0 до максимального числа потоков. Внутри этого цикла я могу объявить мой цикл for
частным для каждого потока. Действительно, counter=80
в этом случае. Является ли это оптимальным решением для этой проблемы или есть лучший?
int main(void) {
omp_set_num_threads(8);
int mthreads = omp_get_max_threads();
#pragma omp parallel for private(i)
for (n=0; n<mthreads; n++) {
int id = omp_get_thread_num();
for (i = 0; i<10; i++) {
printf("i: %d thread: %d\n", i, id);
#pragma omp critical
counter++;
}
}
}
printf("counter %d\n", counter);
return 0;
}