主题:请教matmul效率, 跟Blas比较.
yeg001
[专家分:14390] 发布于 2010-04-22 00:44:00
请问有人把矩阵操作和向量操作运算跟BLAS的比较过吗? 如果有可不可以谈谈经验?
回复列表 (共56个回复)
21 楼
zinsser_1982 [专家分:400] 发布于 2010-06-19 10:39:00
优化选项设置里采用O3
22 楼
dongyuanxun [专家分:7180] 发布于 2010-06-19 14:14:00
编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s
23 楼
dongyuanxun [专家分:7180] 发布于 2010-06-19 14:15:00
编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s
24 楼
心灵的温泉 [专家分:0] 发布于 2010-06-21 03:35:00
我的是1.4AT,按你说的应该够用,高速开空调我还跑过160,就是提速慢点。
25 楼
yeg001 [专家分:14390] 发布于 2010-06-22 08:35:00
[quote]编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s[/quote]
我也尝试用BLAS源码做了一个模块. 编译速度慢一点, 进入计算区速度确实很快.
ifort -O3 -xSSE3 -static-intel -msse3 -c BLAS_Package.f
ifort -O3 -xSSE3 -static-intel -msse3 -c test.f90
ifort -O3 -xSSE3 -static-intel -msse3 -o test BLAS_Package.o test.o
consumed CPU_time(s): 3.77442600000000
consumed CPU_time(s): 4.899199999999970E-002
26 楼
vehicle [专家分:310] 发布于 2010-06-22 18:10:00
[quote]编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s[/quote]
请问blas源代码是指lapack里面带的原始代码吗?
27 楼
yeg001 [专家分:14390] 发布于 2010-06-22 19:13:00
[quote][quote]编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s[/quote]
请问blas源代码是指lapack里面带的原始代码吗?[/quote]
有一个单独的blas包下载的, lapack里面也自带了blas.
gotoBlas的我没办法提取源码
28 楼
jason388 [专家分:6150] 发布于 2010-06-25 11:31:00
对于gfortran,可以采用-fexternal-blas -lblas 改变matmul。当用GotoBLAS2版blas并采用上述编译选项后,matmul性能确实大幅度提高。
采用编译选项的好处是程序代码不变。
在我的机器上前述例子,采用GotoBLAS2版(串行)blas后运行时间为:
11s
2.1s
如果采用编译选项则为:
2.12s
2.1s
加不加-O3似乎没什么影响(估计是代码太简单的原因)。
29 楼
f2003 [专家分:7960] 发布于 2010-06-29 10:00:00
[quote][quote]编译好的库的效率都没直接使用源代码来的快
直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
使用matmul : 4.140625s
直接使用blas源代码里的dgemm: 0.03125s[/quote]
我也尝试用BLAS源码做了一个模块. 编译速度慢一点, 进入计算区速度确实很快.
ifort -O3 -xSSE3 -static-intel -msse3 -c BLAS_Package.f
ifort -O3 -xSSE3 -static-intel -msse3 -c test.f90
ifort -O3 -xSSE3 -static-intel -msse3 -o test BLAS_Package.o test.o
consumed CPU_time(s): 3.77442600000000
consumed CPU_time(s): 4.899199999999970E-002
[/quote]
调用库函数的开销, 包括在硬盘上寻找库文件, 在该库文件中寻找被调用的函数, 以及调用函数的操作.
1)把代码集成到自己的程序里可以省去调用库函数的开销。但是如果这种操作是"冷"的, 不是那种在循环中被大量重复的"热"操作, 这种开销就是不重要的.
2)现代操作系统也有缓冲的机制, 并非每次都要读硬盘.
3)使用静态编译, 也可以把代码整合到程序里, 省去了一些开销. 这就是为什么很多人认为数值程序应使用静态连接。
4)上面给出的例子可以集成dgemm源码,这是以dgemm是独立的代码为前提的,这并非总能做到。如果dgemm依赖其他子过程,那些子过程又依赖另外子过程,形成一个规模较大的依赖树,集成所有需要的代码到主程序中就比较麻烦了。
5)动态编译也有它的优势。第一,节省了内存和硬盘空间;第二,升级方便,库函数是需要不断升级、修正bug的,每次都要重新编译程序很麻烦,动态库就可以避免重复编译,所以动态库成为了主流方式,包括ifort/MKL缺省的方式就是动态库。
6)如果程序较大,需要调用的库比较多,库函数之间关系复杂,“连接时优化”就有了用武之地,编译器有相关选项,有兴趣可以研究研究。
7)现代计算机越来越快,让我们可以在代码运行效率与开发效率之间妥协,也不一定就必须把代码优化到极限,兼顾到需要投入的人的精力。
个人愚见,大家姑妄看之。总之,这个世界不是完美的...
30 楼
yeg001 [专家分:14390] 发布于 2010-06-29 12:43:00
考虑到dgemm调用的依赖关系, 所以把整个BLAS都集成进去. 然后算那个例程的. 速度很快.
但是当它和提取出来的lapack集成到我的应用程序里面的时候, 发现计算时间反而比静态调用GOTOBLAS2要慢很多, 接近10倍.
为什么集成到我的程序中就没有提升反而大幅下降呢? 是因为程序大量使用到BLAS的函数吗?
关于这个问题, 我跟dongyuanxun 网友聊过, 他是用IDE直接把子函数加入到工程里面的, 并没有像我这样提取, 他的总结是集成进去会更快一点.
B.T.W. f2003兄,你在这个帖加分到了50, 我没办法在给你加, 请见谅.
我来回复