使用#pragma omp parallel for计算pi得到错误结果,请问出错原因是什么?
你重写的代码存在3个核心错误:
- 语法使用错误:
#pragma omp parallel for指令直接作用于紧跟它的下一个for循环,不需要额外用大括号包裹for循环,多余的大括号会导致OpenMP指令无法正确识别要并行的循环结构。 - 共享变量竞态冲突:累加变量
sum默认是多线程共享的变量,多个线程同时往sum写入累加值时会发生写覆盖,最终sum的结果远小于正确值。需要给OpenMP指令添加reduction(+:sum)子句,让每个线程生成私有sum副本,并行计算结束后自动把所有副本的值累加得到最终的sum结果。 - 临时变量作用域错误:循环内使用的
x是每个线程独立的临时变量,如果你将x定义在并行块外,默认会是多线程共享的变量,多个线程同时修改x会导致计算的x值错乱。你可以直接将x的定义放在循环体内,依靠C语言的块级作用域自动实现线程私有。
修正后的完整代码
#include <omp.h> #include <stdio.h> static long num_steps = 1000000; double step; #define NUM_THREADS 16 int main() { int i; double tdata, pi, sum = 0.0; omp_set_num_threads(NUM_THREADS); step = 1.0 / (double)num_steps; tdata = omp_get_wtime(); #pragma omp parallel for reduction(+:sum) for (i = 0; i < num_steps; i++) { double x = (i + 0.5) * step; sum += 4.0 / (1.0 + x * x); } tdata = omp_get_wtime() - tdata; pi = sum * step; printf("pi = %f and compute time = %f seconds", pi, tdata); return 0; }
内容的提问来源于stack exchange,提问作者anotherone
相关产品推荐
相关产品推荐

