我是OpenMP的新手,不知道这段代码有什么问题,结果没有意义。
#include <omp.h>
#include <stdio.h>
#define N 20
int cnt = 0;
int A[N];
int main (int argc, char *argv[]) {
#pragma omp parallel for
for (int i = 0; i <= N; i++) {
if ((i%2)==0) cnt++;
A[i] = cnt;
printf("i=%d, cnt=%d\n", i, cnt);
}
printf("outside the parallel cnt=%d\n", cnt);
for (int i = 0; i <= N; i++)
printf("A[%d]=%d\n", i, A[i]);
}
编辑: 并行区域外的cnt应该是11,大多数时候它是正确的,但有时它给了我10.对于数组AI理解为什么值与索引不匹配,但我希望数组A如下所示,是有可能吗?
A[0]=1 A[1]=1 A[2]=2 A[3]=2 A[4]=3 A[5]=3 A[6]=4 A[7]=4 A[8]=5 A[9]=5 A[10]=6
A[11]=6 A[12]=7 A[13]=7 A[14]=8 A[15]=8 A[16]=9 A[17]=9 A[18]=10 A[19]=10
A[20]=11
答案 0 :(得分:1)
您的代码有多个错误。让我们首先解决愚蠢的问题。您写入N+1
元素但仅分配N
个元素。将N
更改为21,然后更改
for (int i = 0; i <= N; i++)
到
for (int i = 0; i < N; i++)
但是你的代码还有另一个更微妙的错误。您正在使用induction variable。我不知道在OpenMP中使用归纳变量的简单方法。
在您的情况下,一个简单的解决方法是不使用归纳变量,而是使用
#pragma omp parallel for
for (int i = 0; i < N; i++) {
int j = i / 2 + 1;
A[i] = j;
}
cnt = N/2;
您还可以使用缩减作为cnt
的最终值,但它是多余的且效率较低。
#pragma omp parallel for reduction(+:cnt)
for (int i = 0; i < N; i++) {
if ((i % 2) == 0) cnt++;
int j = i / 2 + 1;
A[i] = j;
}
如果您真的想使用归纳变量,那么您必须执行以下操作:
#pragma omp parallel
{
int ithread = omp_get_thread_num();
int nthreads = omp_get_num_threads();
int start = ithread*N/nthreads;
int finish = (ithread + 1)*N/nthreads;
int j = start / 2;
if (start % 2) j++;
for (int i = start; i < finish; i++) {
if ((i % 2) == 0) j++;
A[i] = j;
}
}
cnt = N/2;
您还可以使用缩减功能来确定cnt
的最终值,但在下面的代码中可以清楚地看出它是多余的。
#pragma omp parallel reduction(+:cnt)
{
int ithread = omp_get_thread_num();
int nthreads = omp_get_num_threads();
int start = ithread*N/nthreads;
int finish = (ithread + 1)*N/nthreads;
int j = start / 2;
if (start % 2) j++;
for (int i = start; i <finish; i++) {
if ((i % 2) == 0) {
j++; cnt++;
}
A[i] = j;
}
}