OpenMP с использованием циклов и сокращений массивов

Я написал программу следующим образом:

#include "omp.h"#include "stdio.h"
int main()
{
int i, j, cnt[] = {0,0,0,0};
#pragma omp parallel
{
int cnt_private[] = {0,0,0,0};
#pragma omp for private(j)
for(int i = 1 ; i <= 10 ; i++) {
for(j = 1 ; j <= 10 ; j++) {
int l= omp_get_thread_num();
cnt_private[l]++;
}
#pragma omp critical
{
for(int m=0; m<3; m++){
cnt[m] = cnt_private[m];
}
}
printf("%d %d %d %d %d\n",i,cnt[0],cnt[1],cnt[2],cnt[3]);
}
}
return 0;
}

Он должен вывести количество выполнений каждого потока для каждого i. Поскольку только один поток принимает конкретное значение i, ожидаемый результат должен удовлетворять сумме каждой строки как 100. Но я получаю вывод в форме:

1 10 0 0 0
2 20 0 0 0
3 30 0 0 0
7 0 0 10 0
8 0 0 20 0
9 0 0 0 0
10 0 0 0 0
4 0 10 0 0
5 0 20 0 0
6 0 30 0 0

В чем проблема? Может ли это быть в моем фундаментальном понимании OpenMP? или мой процесс сокращения неправильный?
(Я использую компилятор GNU GCC и 4-ядерный компьютер)
Шаги компиляции:

g++ -fopenmp BlaBla.cpp
export OMP_NUM_THREADS=4
./a.out

0

Решение

Я не понимаю, почему сумма каждого ряда должна быть 100.

Вы объявили cnt_private быть частным:

#pragma omp parallel
{
int cnt_private[] = {0,0,0,0};
// ...
}

Таким образом, сохраненное в нем суммирование не распределяется между потоками. Если нить l выполняется только cnt_private[l] будет увеличен, а все остальные останутся равными нулю. Затем вы осматриваете содержание cnt_private в cnt, который не является частным. Вы назначаете каждую запись, которая также равна нулю!

#pragma omp critical
{
for(int m=0; m<4; m++){ // I guess you want 'm<4' for the number of threads
cnt[m] = cnt_private[m];
}
}

С i от 0 до 10 и программа использует 4 потока, каждый поток получает от 2 до 3 i«S. Таким образом, я ожидаю, что сумма каждого столбца будет 30 (10 + 20) или 60 (10 + 20 + 30).

1

Другие решения