我正在处理一个信号矩阵,我的目标是计算一行中所有元素的总和。该矩阵由以下结构表示:
typedef struct matrix {
float *data;
int rows;
int cols;
int leading_dim;
} matrix;
我必须提到矩阵是以列优先的方式进行存储(http://en.wikipedia.org/wiki/Row-major_order#Column-major_order),这也解释了公式column * tan_hd.rows + row
来检索正确的索引。
for(int row = 0; row < tan_hd.rows; row++) {
float sum = 0.0;
#pragma omp parallel for reduction(+:sum)
for(int column = 0; column < tan_hd.cols; column++) {
sum += tan_hd.data[column * tan_hd.rows + row];
}
printf("row %d: %f", row, sum);
}
没有使用OpenMP编译指示,结果是正确的,如下所示:
row 0: 8172539.500000 row 1: 8194582.000000
一旦按照上述方式添加
#pragma omp...
,就会返回不同(错误)的结果。row 0: 8085544.000000 row 1: 8107186.000000
根据我的理解,
reduction(+:sum)
为每个线程创建了私有的 sum
副本,在循环完成后将这些部分结果相加并重新写回全局变量 sum
。那我做错了什么呢?感谢您的建议!
column
是局部变量。对于每个并行操作,column
都会被初始化为零,但实际上不应该这样做。将其移出for
循环即可。 - MYMNeoomp
部分期间,tan_hd.data
和row
都没有被更改/写入,omp
应该负责column
... - Max Plauth