我正在学习使用openmp通过积分计算pi的例子。在串行中,我运行以下C代码:
double serial() {
double step;
double x,pi,sum = 0.0;
step = 1.0 / (double) num_steps;
for (int i = 0; i < num_steps; i++) {
x = (i + 0.5) * step; // forward quadature
sum += 4.0 / (1.0 + x*x);
}
pi = step * sum;
return pi;
}
我正在将这个与使用并行for和reduction的omp实现进行比较:
double SPMD_for_reduction() {
double step;
double pi,sum = 0.0;
step = 1.0 / (double) num_steps;
#pragma omp parallel for reduction (+:sum)
for (int i = 0; i < num_steps; i++) {
double x = (i + 0.5) * step;
sum += 4.0 / (1.0 + x*x);
}
pi = step * sum;
return pi;
}
当num_steps = 1,000,000,000,omp情况下使用6个线程,我进行编译并计时:
double start_time = omp_get_wtime();
serial();
double end_time = omp_get_wtime();
start_time = omp_get_wtime();
SPMD_for_reduction();
end_time = omp_get_wtime();
不使用任何cc编译器优化的情况下,串行运行时间约为4秒,而omp的运行时间为0.66秒。如果使用-O3标志,串行运行时会降至“0.000001秒”,而omp运行时间几乎不变。这是怎么回事?是在使用矢量指令,还是代码或计时方法很差?如果是矢量化,为什么omp函数没有受益呢?
值得注意的是,我使用的机器是一台现代的6核Xeon处理器。
谢谢!