OpenMP程序在Linux与Windows下的加速性能差异很大,这是为什么?
一个四路4核的工作站,装有windows与linux两个操作系统,都是64位的。但同一段OpenMP程序,在Windows中使用VS2010或IntelC++编译器编译,...
一个四路4核的工作站,装有windows与linux两个操作系统,都是64位的。但同一段OpenMP程序,在Windows中使用VS 2010或Intel C++编译器编译,能达到比较良好的加速比,8个线程在7.5左右,16个线程在12左右。反而在linux下,无论是g++还是icpc编译,2个线程1.6左右,4个线程1.2左右,8个线程与16个线程的执行时间要远大于串行执行。
用Vtune性能分析器分析Hotspots与Locks and Waits,发现:
在Windows下主要是Omp barrier的开销增加了wait time影响了性能,这个很正常;
在Linux下Locks and Waits分析得出的wait time只是显示了几毫秒的IO开销,但在Hotspots中,占用时间最长的已经不是程序本身的计算,在centOS系统中运行下占用时间最多的是VDSO开销,随线程数线性增长,8个线程时占用总CPU时间已经达到70%;在RedHat系统下运行则是属于libc-2.5.so的两个函数,分别是_lll_unlock_wake_private与_lll_lock_wait_private,执行时间与VDSO开销类似。
在循环中使用到的shared变量在一次循环的计算过程中均是只读的,只是在最后的循环结束处需要将计算的结果填入到一个数组中,而这个数组是共享的。那么,linux环境下的开销到底可能是来自哪里呢? 展开
用Vtune性能分析器分析Hotspots与Locks and Waits,发现:
在Windows下主要是Omp barrier的开销增加了wait time影响了性能,这个很正常;
在Linux下Locks and Waits分析得出的wait time只是显示了几毫秒的IO开销,但在Hotspots中,占用时间最长的已经不是程序本身的计算,在centOS系统中运行下占用时间最多的是VDSO开销,随线程数线性增长,8个线程时占用总CPU时间已经达到70%;在RedHat系统下运行则是属于libc-2.5.so的两个函数,分别是_lll_unlock_wake_private与_lll_lock_wait_private,执行时间与VDSO开销类似。
在循环中使用到的shared变量在一次循环的计算过程中均是只读的,只是在最后的循环结束处需要将计算的结果填入到一个数组中,而这个数组是共享的。那么,linux环境下的开销到底可能是来自哪里呢? 展开
1个回答
展开全部
Linux的线程是用轻量级进程实现的,比Windows真正的线程开销大,
特别是没有加装Native POSIX Thread Library的Linux Kernel上,差距更明显。
我想是不是该从这方面想想原因和解决办法。
你的Linux Kernel至少得是2.6以上
特别是没有加装Native POSIX Thread Library的Linux Kernel上,差距更明显。
我想是不是该从这方面想想原因和解决办法。
你的Linux Kernel至少得是2.6以上
追问
刚才又排查了一下,发现是rand()函数的原因,在Openmp并行区之前用srand(time(NULL)获取了种子,然后在每次循环中用到了多次rand()函数,把rand()给注释掉加速比就接近于线性了。请问这是为什么呢?rand()函数为什么会带来那么大的CPU时间开销?
追答
因为g++的rand()其实是高可靠性random()函数,
而vc++的rand()算法就比较简单,速度快而可靠性低。
BSD/GCC 高可靠性 random():
初始化——srandom((unsigned)time(NULL));
使用——random(),生成 0 ~ RAND_MAX 间的随机整数,RAND_MAX在 stdlib.h 中预定义。
注意无论是vc++简单算法的rand()还是BSD/GCC标准的random(),都不是线程安全的,
换句话说,它不能保证多线程高性能并行计算中不同线程之间随机序列的独立无关性!
线程安全的随机数生成函数是rand_r 或高可靠性的 drand48_r 。
详细说明参见我的百度文档:http://wenku.baidu.com/view/422cd0d233d4b14e852468a1.html
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询