OpenMP 使用循环和数组缩减
OpenMP using loops and array reductions
我写了一个程序如下:
#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
我不明白为什么每行的总和应该是 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)。
我写了一个程序如下:
#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
我不明白为什么每行的总和应该是 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)。