我正在试验OpenMP.我写了一些代码来检查它的性能.在使用Kubuntu 11.04的4核单Intel CPU上,使用OpenMP编译的以下程序比没有OpenMP编译的程序慢大约20倍.为什么?
我用g ++编译了它-g -O2 -funroll-loops -fomit-frame-pointer -march = native -fopenmp
#include <math.h>
#include <iostream>
using namespace std;
int main ()
{
long double i=0;
long double k=0.7;
#pragma omp parallel for reduction(+:i)
for(int t=1; t<300000000; t++){
for(int n=1; n<16; n++){
i=i+pow(k,n);
}
}
cout << i<<"\t";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
ole*_*enz 15
问题是变量k被认为是共享变量,因此必须在线程之间同步.避免这种情况的可能解决方案是:
#include <math.h>
#include <iostream>
using namespace std;
int main ()
{
long double i=0;
#pragma omp parallel for reduction(+:i)
for(int t=1; t<30000000; t++){
long double k=0.7;
for(int n=1; n<16; n++){
i=i+pow(k,n);
}
}
cout << i<<"\t";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在下面的注释中跟随Martin Beckett的提示,不是在循环中声明k,而是在循环外声明k const.
否则,ejd是正确的 - 这里的问题似乎并不是很糟糕的并行化,而是代码并行化时的错误优化.请记住,gcc的OpenMP实现非常年轻,远非最佳.