OpenMP使用循环和数组缩减

时间:2015-06-23 17:02:36

标签: c++ parallel-processing openmp computation

我写了一个程序如下:

#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  

1 个答案:

答案 0 :(得分:1)

我不明白为什么每行的总和应该是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个。因此,我希望每列的总和为30(10 + 20)或60(10 + 20 + 30)。