这是我第一次使用OpenMP,我觉得我在实施以下内容时存在核心误区:
#include <omp.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int i, n;
float a[100], b[100], result;
/* Some initializations */
n = 100;
result = 0.0;
for (i=0; i < n; i++) {
a[i] = i * 1.0;
b[i] = i * 2.0;
}
//pragma statement for omp here
for (int i=0; i < n; i++)
result = result + (a[i] * b[i]);
printf("Final result= %f\n",result);
}
该程序旨在计算涉及求和的点积。
在this question中,回答的人建议使用简化来使用#pragma omp parallel for reduction(+:results)
在for循环中实现并行求和,但是在进行实验时,我得到了相同的答案,就像我刚刚使用#pragma omp parallel for
一样,我天真地假设是正确的,但让我感到不安,因为我找不到任何文件说这是不正确的。解释为什么我可能错了会有所帮助。
答案 0 :(得分:3)
使用#pragma omp parallel for reduction(+:result)
是正确的。 #pragma omp parallel for
错了。后者意味着所有线程都以不受保护的方式写入result
。这是一个classical race condition。在实践中,您可能会巧合地得到相同的结果,例如因为硬件原子工作,操作系统不会在不同的核心上调度线程或只是纯粹的运气。不要被愚弄,代码仍然是错误的。
不幸的是,你不能证明代码是正确的,只是通过显示它产生一些正确的结果。只是这样你就不能通过测试它们产生相同的结果几次来显示两个相等的代码。或者换句话说,错误的代码并不总是容易显露出来。