我正在尝试使用 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;
}
问题是变量 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;
}
按照 Martin Beckett 在下面的评论中的提示,您也可以在循环外部声明 k const,而不是在循环内部声明 k。
否则,ejd是正确的——这里的问题似乎不是并行化不好,而是代码并行化时优化不好。请记住,gcc 的 OpenMP 实现还很年轻,远非最佳。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)