【发布时间】:2014-03-16 23:56:21
【问题描述】:
我刚刚学习 OpenMP,在并行化 for 循环时遇到问题,我很确定它符合并行化标准。下面是 SSCCE,它展示了我在实际代码中遇到的问题。
问题是,当我使用 OpenMP 编译和运行它时,wr[i][j] 和 wi[i][j] 的内容总是 1.00和 0.00 分别。如果我注释掉编译指示并连续运行代码,那么 wr 和 wi 包含我期望的值。即使在使用 OpenMP 编译后仅使用 1 个线程运行代码,该代码仍然会出现问题。必须注释掉编译指示才能连续运行它。
我认为我的问题与 wr 和 wi 是指向指针的指针有关。如果是这种情况,我该如何解决?如果这不是问题,那是什么?非常感谢任何见解。
// compilation gcc -fopenmp -o test test.c -lm
// usage ./test <Problem Size (Must be a power of 2)> <Num Threads>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[]){
double **wr, **wi;
double *data;
double wtemp, wpr, wpi, theta;
int i, j, n, nn, mmax, istep, num_mmax_iterations, T;
const int isign = -1;
if(argc < 3){
printf("ERROR, usage: %s <N (must be a power of 2)> <T>\n", argv[0]);
exit(1);
} else {
n = atoi(argv[1]);
T = atoi(argv[2]);
}
num_mmax_iterations = log2(n);
wr = malloc(sizeof(double *) *num_mmax_iterations);
wi = malloc(sizeof(double *) *num_mmax_iterations);
mmax = 2;
for(i = 0; i < num_mmax_iterations; i++) {
wr[i] = malloc(sizeof(double) * (mmax >> 1));
wi[i] = malloc(sizeof(double) * (mmax >> 1));
wr[i][0] = 1.0;
wi[i][0] = 0.0;
mmax <<= 1;
}
mmax = 2;
#pragma omp parallel for private(i, j, theta, wtemp, wpr, wpi) firstprivate(mmax) shared(num_mmax_iterations, wr, wi) num_threads(T)
for(i = 0; i < num_mmax_iterations; i++) {
theta = isign * (6.28318530717959 / mmax);
wtemp = sin(0.5 * theta);
wpr = -2.0 * wtemp * wtemp;
wpi = sin(theta);
for(j = 1; j < (mmax >> 1); j++) {
wr[i][j] = wr[i][j - 1] * wpr - wi[i][j - 1] * wpi + wr[i][j - 1];
wi[i][j] = wi[i][j - 1] * wpr + wr[i][j - 1] * wpi + wi[i][j - 1];
}
mmax <<= 1;
}
for(i = 0; i < num_mmax_iterations; i++) {
for(j = 0; j < (mmax >> 1); j++) {
printf("%.2f | %.2f\n", wr[i][j], wi[i][j]);
}
}
for(i = 0; i < num_mmax_iterations; i++) {
free(wr[i]);
free(wi[i]);
}
free(wr);
free(wi);
return 0;
}
编辑
在运行 ./test 8 1 时移除编译指示后的预期输出
1.00 | 0.00
0.00 | 0.00
0.00 | 1.00
0.00 | -0.00
1.00 | 0.00
-0.00 | -1.00
0.00 | 1.00
-1.00 | 0.71
1.00 | -0.00
0.71 | -0.71
-0.00 | 0.00
-0.71 | -0.71
0.00 | -1.00
-0.71 | -0.71
-1.00 | 1.00
-0.71 | 0.92
1.00 | 0.00
-0.00 | -1.00
0.00 | 1.00
-1.00 | 0.71
1.00 | -0.00
0.71 | -0.71
-0.00 | 0.00
-0.71 | -0.71
0.00 | -1.00
-0.71 | -0.71
-1.00 | 1.00
-0.71 | 0.92
1.00 | 0.71
0.92 | 0.38
0.71 | -0.00
0.38 | -0.38
1.00 | 0.00
0.71 | -0.71
-0.00 | -1.00
-0.71 | -0.71
0.00 | 1.00
-0.71 | 0.92
-1.00 | 0.71
-0.71 | 0.38
1.00 | -0.00
0.92 | -0.38
0.71 | -0.71
0.38 | -0.92
-0.00 | 0.00
-0.38 | -0.38
-0.71 | -0.71
-0.92 | -0.92
1.00 | 0.00
0.92 | -0.38
0.71 | -0.71
0.38 | -0.92
-0.00 | -1.00
-0.38 | -0.92
-0.71 | -0.71
-0.92 | -0.38
0.00 | 0.00
-0.38 | 0.00
-0.71 | 0.00
-0.92 | 0.00
-1.00 | 0.00
-0.92 | 0.00
-0.71 | 0.00
-0.38 | 0.00
编译指示保持原样运行的实际输出 ./test 8(任意数量的线程)
1.00 | 0.00
1.00 | 0.00
1.00 | 0.00
注意:实际问题的规模要大得多,预期数据的变化通常比上面的要大。
【问题讨论】:
-
您能否提供一个正确和错误输出的示例,因为我尝试了您的代码,但我真的不明白出了什么问题。
-
@user3018144 我刚刚添加了预期和实际输出。
标签: c multithreading parallel-processing openmp