为什么OpenMP版本较慢
Why OpenMP version is slower?
我正在试用OpenMP。我写了一些代码来检查它的性能。在使用Kubuntu 11.04的4核单英特尔CPU上,以下使用OpenMP编译的程序比未使用OpenMP的程序慢约20倍。为什么?
我通过g++-g-O2-funroll循环-fmit帧指针-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实现还很年轻,远未达到最佳状态。
最快的代码:
for (int i = 0; i < 100000000; i ++) {;}
稍慢的代码:
#pragma omp parallel for num_threads(1)
for (int i = 0; i < 100000000; i ++) {;}
2-3倍慢的代码:
#pragma omp parallel for
for (int i = 0; i < 100000000; i ++) {;}
不管它在{和}之间是什么。简单的;或者更复杂的计算得到相同的结果。我在Ubuntu 13.10 64位下编译,使用gcc和g++,尝试不同的参数-ansi-迂腐错误-Wall-Wextra-O3,并在英特尔四核3.5GHz上运行。
我想线程管理开销出了问题?OMP在每次需要线程时都创建一个线程,然后销毁它,这似乎并不明智。我以为会有四个(或八个)线程在需要的时候运行或睡觉。
我在GCC上观察到类似的行为。然而,我想知道在我的情况下,它是否在某种程度上与模板或内联函数有关。您的代码也在模板或内联函数中吗?请看这里。
然而,对于非常短的循环,您可能会观察到与线程切换相关的一些小开销,如您的情况:
#pragma omp parallel for
for (int i = 0; i < 100000000; i ++) {;}
如果您的循环执行时间非常长,甚至只有几毫秒甚至几秒钟,那么在使用OpenMP时,您应该观察到性能的提升。但只有当你有一个以上的CPU。您拥有的内核越多,OpenMP的性能就越高。
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- OpenMP阵列性能较差
- 导入库可以跨dll版本工作吗
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- OpenMP:并行更新数组总是需要减少数组吗
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 如何使用OpenMP并行这两个循环
- 将全局外部变量的私有版本与 OpenMP 结合使用
- 必须执行哪些操作才能将程序转换为强大的 OpenMP 感知版本
- 在数组中查找最大元素OpenMP和PPL版本的运行速度比串行代码慢得多
- 针对Microsoft Visual C++的OpenMP更新仍然停留在版本2
- 为什么OpenMP版本较慢
- 为什么ubuntu 12.04下的OpenMP比串行版本慢
- OpenMP 并行版本的运行速度比串行版本慢