FLENS

前面对 boost.numeric.uBLAS 使用的比较多,当时也提到过 LAPACK 的功能可以通过 boost.numeric_binding 来做。最近看见了 flens,据它说性能比 uBLAS 更好,非常吃惊,加上了 expression template 的 uBLAS 还是不够快?那 flens 到底有什么 trick?

看样子主要有两个因素:uBLAS 号称 generic BLAS,也就是说很可能没有做对应的优化,而只是把容器设计的方便、expression template 避免产生额外的开销;但是 BLAS 的实现应该是有不少相关优化的,也就是说如果要拿这个 generic BLAS 与特定的 BLAS 比,这个可能就是比不过。

第二个很可能 uBLAS 实现的本身也有一些问题,与完全不使用具体 BLAS binding 的 FLENS 相比(评测见),在矩阵乘法方面还是差距很大的。

当然 uBLAS 通过 numeric binding 是可以提高性能的,但是正如 FLENS 所说的,那似乎也比不上 FLENS 啊。那么 FLENS 怎么提供自然而然的 binding 呢(FLENS 对 BLAS 的 binding 是建立在 CBLAS 上的,而 CBLAS 提供了 row-major 和 column major 两种)?compilation binding:比如我们有两个容器,一个是矩阵,一个是向量,我们的 expression template 里面实际上可以获得类型的推到结果,比如 double 和 double,后面产生的也是 double,另外矩阵使用了什么 storage(如 full storage、band storage 还是 package storage)、矩阵自身的结构(对称、Hermite、三角还是一般),这样就会调用不同的 BLAS 函数进行实际操纵(这大概是利用 traits 之类的 bind 到具体的函数上的)。因此很重要的一点 FLENS 必须对其 parsed tree 进行优化,bind 到不同的 BLAS 调用上。比较没弄明白的是,这样一来一个复杂的调用(不能被一个 BLAS call 给 cover),是否还是能利用 expression template 避免产生中间的变量呢?FLENS 的选择似乎是“尽量”使用 BLAS 来做,比如 r = x + y + z 这种操作会利用 expression template 的特性弄成 r = x,之后调用 BLAS 将 y 和 z 加到 r 上。

另外一个问题是将 matrix/vector 操作混合会产生一些意想不到的问题,比如 y = Ax 这种计算可以利用 expression template 很容易实现,但是 x = Ax 这种语句就必须特殊处理,让 Ax 的结果能够临时存放在别处。

最后一个是扩展性问题。特别是在 PDE 问题常见的是为特殊的矩阵设计了特殊的结构。那么为 CRTP 设计的接口就必须足够有灵活性才能发挥各种特殊结构的作用,这往往是个很矛盾的事情。

我们通过 CVS 下载了 FLENS,它的编译相对容易,一般如果系统已经装好了 ATLAS,就可以直接让 FLENS 与之 bind。但是它的一个比较大的问题是在 Mac 下面没有比较好的 compilation setup,很多参数需要手工设置或者事后用 install_name_tool 进行调整。一些细节参看这里

下面是 FLENS 的部分代码,

typedef SparseGeMatrix<CRS<double> > Mat;
typedef DenseVector<Array<double> >  Vec;
Mat A(n, n, 3);
Vec b(n), x(n), r(n);
r = b - A*x;

类似的 uBLAS 的实现如下

namespace bnu = boost::numeric::ublas ;
bnu::compressed_matrix<double, row_major> A (size,size);
bnu::vector<double> b (size), r(size), x(size);
r = prod(A, x) - b;

但是两者的效率的确差了很多

这是使用 CVS 的 FLENS 与 1.49 的 boost 带的 uBLAS 做的比较

这是使用 pylab 画出来的

$ ipython-2.6 -pylab
In [1]: a = loadtxt ('data.txt')
In [2]: figure (1)
In [4]: loglog(a[:, 0], a[:, 1], 'b-')
In [5]: loglog(a[:, 0], a[:, 2], 'r-')
In [6]: title ('FLENS vs uBLAS')
In [7]: grid (True)
In [8]: xlabel ('scale')
In [9]: ylabel ('time')

有必要在以后尽量使用 FLENS 吗?感觉 uBLAS 就几个头文件而已,方便一点吧。如果要严肃一点,那就 FLENS。

——————
For we will destroy this place, because the cry of them is waxen great before the face of the LORD; and the LORD has sent us to destroy it.

Advertisements
FLENS

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s