回 帖 发 新 帖 刷新版面

主题:请教matmul效率, 跟Blas比较.

请问有人把矩阵操作和向量操作运算跟BLAS的比较过吗? 如果有可不可以谈谈经验?

回复列表 (共56个回复)

21 楼

优化选项设置里采用O3

22 楼

编译好的库的效率都没直接使用源代码来的快

直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
 使用matmul : 4.140625s
 直接使用blas源代码里的dgemm: 0.03125s

23 楼

编译好的库的效率都没直接使用源代码来的快

直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
 使用matmul : 4.140625s
 直接使用blas源代码里的dgemm: 0.03125s

24 楼

我的是1.4AT,按你说的应该够用,高速开空调我还跑过160,就是提速慢点。

25 楼

[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 楼

[quote]编译好的库的效率都没直接使用源代码来的快

直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
 使用matmul : 4.140625s
 直接使用blas源代码里的dgemm: 0.03125s[/quote]
请问blas源代码是指lapack里面带的原始代码吗?

27 楼

[quote][quote]编译好的库的效率都没直接使用源代码来的快

直接使用blas源代码,就是编译时间长一些。
编译开关为 ifort /O3 /fast /QxHost
测试结果为
 使用matmul : 4.140625s
 直接使用blas源代码里的dgemm: 0.03125s[/quote]
请问blas源代码是指lapack里面带的原始代码吗?[/quote]
有一个单独的blas包下载的, lapack里面也自带了blas.
gotoBlas的我没办法提取源码

28 楼

对于gfortran,可以采用-fexternal-blas -lblas 改变matmul。当用GotoBLAS2版blas并采用上述编译选项后,matmul性能确实大幅度提高。
采用编译选项的好处是程序代码不变。

在我的机器上前述例子,采用GotoBLAS2版(串行)blas后运行时间为:
11s
2.1s
如果采用编译选项则为:
2.12s
2.1s

加不加-O3似乎没什么影响(估计是代码太简单的原因)。

29 楼

[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 楼

考虑到dgemm调用的依赖关系, 所以把整个BLAS都集成进去. 然后算那个例程的. 速度很快.
但是当它和提取出来的lapack集成到我的应用程序里面的时候, 发现计算时间反而比静态调用GOTOBLAS2要慢很多, 接近10倍.
为什么集成到我的程序中就没有提升反而大幅下降呢? 是因为程序大量使用到BLAS的函数吗?
关于这个问题, 我跟dongyuanxun 网友聊过, 他是用IDE直接把子函数加入到工程里面的, 并没有像我这样提取, 他的总结是集成进去会更快一点.


B.T.W. f2003兄,你在这个帖加分到了50, 我没办法在给你加, 请见谅.

我来回复

您尚未登录,请登录后再回复。点此登录或注册