- 积分
- 18
- 注册时间
- 2006-9-6
- 仿真币
-
- 最后登录
- 1970-1-1
|
本帖最后由 myleader 于 2011-6-13 01:24 编辑
此前http://forum.simwe.com/viewthread.php?tid=931180
曾经讨论过豪华老爷车与后发优势。
Lapack在开源科学软件中的地位实在是太牢固了,此前有人写过一些软件,意图将其取而代之。这些挑战者中包括MTL、TNT等等,不过都没有成器,现在都已经处于长期不更新状态,事实上已经停止开发。而Boost中的ublas目前虽然还在进展,不过进展微乎其微。
这些软件之所以不能取代lapack,原因很复杂,不过对于科学运算的软件包而言,其实原因很简单:慢。Lapack是用Fortran写成的,Fortran写成的程序通常速度要快,当然这不是说C写不出那么快的程序,毕竟C可以在非常底层操作,只是Fortran可以把优化的任务交给编译器,而C大多需要程序员自己掌握,所以大多数人写出的C程序比Fortran要慢,而如果真的追求极速,那C程序的可读性就要大幅降低了。这一点在ublas上尤为明显,它的速度太慢了。
这次给大家隆重介绍一位新贵
http://eigen.tuxfamily.org/index.php?title=Main_Page
Eigen是用C++模板技术写成的数学软件包(此前MTL也曾经用模板技术意图在速度上超越Lapack,不过后来也不知道出了什么事情,项目几经易手,现在已经奄奄一息了。)不过Eigen正在前进,2011年5月刚刚发布了新一代的软件包,最新版本是3.0.1
大家可以访问
http://eigen.tuxfamily.org/index.php?title=Benchmark
看一看它和其他线性代数包的速度对比,其测试结果不逊于gotoblas和MKL。
更重要的是,它是用C++写成的,对于我这种不会使用Fortran的人而言,简直就是天大的福音
eigen是LGPL的,换句话说,只要你采用动态链接,那么你可以不开放你的源代码,eigen没有开源传染性
而且其文档非常详尽,基本上只要你熟悉C++就可以立即上手。虽然他的函数命名和MATLAB还是稍有不同,不过提供了一份对照表,照着做就可以了。
而且,它不需要使用lapack/blas作为后端,直接使用头文件和标准C库函数就可以了,这样采用eigen发布程序的时候就不需要额外附带一个lapack.dll了,而且其开发难度也大幅降低了。要知道,如果依赖lapack后端,就需要针对编译器和操作系统预先制作二进制库文件,而这个过程很烦的,还容易产生各种问题,如果将来你需要更换操作系统或者编译器,那就更烦了,如果你发布了程序,而用户使用的环境和你不一样,你还要专门再处理。有了eigen,可以甩开lapack.dll了
根据官方的说明,eigen适用于多种编译器,在中国使用最广泛的当然是微软的VC了,不过我个人更愿意使用mingw——主要因为它是绿色的,而且升级比较快,出了补丁可以自己装,微软的东西就算是报告了bug,也得等下一个新版本修正,而且mingw更新快的话,还可以很快追上最新的技术,比如多线程支持、最新的CPU指令集等等。
不过eigen毕竟年轻,很多功能还不完善。根据eigen官方的路线图,他们已经完全实现了blas的功能,但是lapack的功能还没有全部完成。不过eigen的目标并非简单的线性代数包,而是全功能。目前他们已经实现了openmp多线程支持,不过就像他们自己说的,openmp到底干了什么,他们并不清楚,所以线程安全是个问题;目前看来他们似乎两个方向都在考虑,一个是采用lapack作为后端,lapack/blas如果支持多线程,那就直接用,另一个是自己写多线程,不过工作量大,所以可能一时半会实现不了。另外,信号处理、统计学、优化……各种数学常用工具都在路线图中,而且实际上也出现在unsupported特性中,就是说这些特性也许可以用,不过官方目前不宣称可用,也就是试用的意思。
对我个人而言,现阶段blas的功能我用的倒是比lapack的多,所以不是十分在意这种事情。实在不行那就自己写点函数嘞,不过我估计官方不会接受我的源码的,我的水平比较烂
这个软件现在风头很大。原本是KDE的一个子项目,现在越做越大了,他们目前的主页上说法国科学院INRIA提供了一个工作岗位。说起来这个信号很暧昧,因为INRIA为了对抗MATLAB开发了一个开源的线性代数工具软件scilab,本来scilab的后端是lapack/blas,而且它的blas使用的是atlas,但是由于atlas在windows平台编译时需要Cygwin模拟环境,所以速度要慢很多,而且最新的3.8系列我是没编译出来,大概看了一下,scilab自带的atlas是3.6的。我个人还是更喜欢新版,因为新版总归是要解决旧版的一些问题的,而且3.6版最多只能支持到sse指令集,更新的就不行了,这样效能就差了很多。那么INRIA支持eigen说明什么呢?也许是觉得eigen可能在未来能够扛起与lapack分庭抗礼的大旗吧。
这个软件的安装也很简单,下载了源代码以后解压缩到硬盘上。然后到cmake网站下载一个cmake
http://www.cmake.org/cmake/resources/software.html
最新版是2.8.4
里面有一个gui工具,图形化的,很简单
启动cmake以后,第一项是源码目录,指定到刚刚解压缩的目录就好了
第二项是“构建目录”,其实就是说在构建过程中,会生成一些临时文件,而这些临时文件就放在这里,通常我会在源码目录下新建一个build子目录来充当这个角色。
然后点击configure,第一次会提示你选择编译器,我用的是mingw,就选mingw好了。不知道为什么,我的cmake第一次会出错,提示探测mingw编译器失败,不过再点一次就好了,然后它就会自动探测配置选项,然后出现在界面那个清单里
接下来对各个选项进行配置,最重要的一点是选择安装目录,其实安装过去也就是写头文件,不会写注册表或者配置文件,不过你如果搞错了到最后就会找不到了。这个目录设定在哪其实都可以,如果你想管理方便那就放在你自己的源码目录,如果你想用着方便,就放到编译器的include目录
其次还有一些选项在下面,重要的有这么几项:
1)openmp支持多线程,速度会提高,不过线程安全性不可控(或者说不是由eigen来控制的),我选了
2)sse系列指令集,提高速度用,根据gcc官方的说明,采用sse选项支持数学矢量运算会有计算错误的风险,不过我还是选了
3)x87,这个指的是x87数学协处理器指令集,主要包含了c库函数math.h中的功能,不过由于当年设计的不合理,现在这个指令集已经比较慢了,不要选
4)默认采用“行”存储。这个是矩阵在内存中的存储格式,Fortran默认都是“列”格式存储的,eigen默认也是“列”,这个看您意思,如果你需要和Fortran联合编程,最好不要选。不过在未来编写程序时这个可以在源代码里面设定
5)C++0x支持,我会选
其他的你自己把握就好了
然后点击generate,就会在build目录下生成Makefile和所需的文件,然后进入build目录,敲击命令就在安装目录得到了整理好的eigen头文件
按照官方文档所述,其实安装起来不用那么麻烦,只要把头文件拷贝到对应目录就可以了。不过我经过实际检测,不行。如果你在cmake阶段选择了mingw编译器,那么生成的头文件是不能给VC调用的,会出错;而且cmake阶段不同编译器的选项也不尽相同,如果是VC编译器,最多只能支持到sse2指令集,sse3、sse4等等是不支持的,如果你想让你的程序支持更新的指令集,那就等着i7自己来做优化吧。(据说i7可以硬件支持指令集转换)
来测试一段代码- #include <iostream>
- #include <ctime>
- #include <Eigen/Core>
- #include <Eigen/Dense>
- using namespace std;
- using namespace Eigen;
- int main()
- {
- int size=2048, N=10;
- clock_t start, end;
- MatrixXf A = MatrixXf::Random(size,size);
- MatrixXf B = MatrixXf::Random(size,size);
- MatrixXf Z = MatrixXf::Random(size,size);
- cout <<"start"<<endl;
- start = clock();
- for(int i=0; i<N; ++i)
- {
- Z = A*B; // or Z = A+B+C ... etc
- cout<<i+1<<endl;
- }
- end = clock();
- cout << "time taken = " << 1.0*(end-start)/CLOCKS_PER_SEC << endl;
- system("pause");
- return(0);
- }
复制代码 这段代码先生成3个2k*2k的随机矩阵,然后重复相乘10次,最后看看计算时间如何。
我的测试平台是:
core i3
win7x86没办法,公司的机器,不能自己换64位系统
mingw-4.5.3
优化参数- -O2 -m32 -mmmx -msse -msse2 -msse3 -msse4 -msse4.1 -msse4.2 -fopenmp
复制代码 生成文件482k,实际执行时间在9.6s到13s之间
我还用armadillo配合gotoblas2静态链接做了一个一样的测试,生成文件452k,实际执行时间11s到15s(这只是为了测试,因为动态链接会损失速度的,但是静态链接原则上违反了LGPL,大家发布程序的时候,不要这么干,还是额外提供一个lapack.dll吧)
这个结果让我万分惊讶,反复测试,eigen都比gotoblas要快多于10%,彻底打破了我原本印象中gotoblas王者的形象,现在大家明白我为什么隆重介绍这个新贵了吧。看来法国科学院选择它还是没错的。我也正在考虑放弃armadillo+lapack的组合,采用eigen来继续我的计算工作。 |
评分
-
1
查看全部评分
-
|