BOOST uBLAS矩阵产品极其缓慢

时间:2011-10-17 19:05:42

标签: c++ performance boost ublas boost-ublas

有没有办法提高ublas产品的性能?

我有两个矩阵A,B我想多次/添加/子/ ....

在MATLAB与C ++中,我获得了2000x2000矩阵操作的以下时间[s]

OPERATION | MATLAB | C++ (MSVC10)
A + B     |  0.04  |  0.04
A - B     |  0.04  |  0.04
AB        |  1.0   | 62.66
A'B'      |  1.0   | 54.35

为什么这里有如此大的性能损失?

矩阵只是真正的双打。 但我也需要正定义,对称的矩形产品。

编辑: 代码很简单

matrix<double> A( 2000 , 2000 );
// Fill Matrix A
matrix<double> B = A;

C = A + B;
D = A - B;
E = prod(A,B);
F = prod(trans(A),trans(B));

编辑2: 结果是10 trys的平均值。 stddev小于0.005

我希望因素可能是2-3而不是50(!)

编辑3: 所有内容都在Release(NDEBUG / MOVE_SEMANTICS / ..)模式中进行了操作。

编辑4: 产品结果的预分配矩阵不会影响运行时间。

4 个答案:

答案 0 :(得分:4)

发布您的C +代码以获取有关任何可能的优化的建议。

然而,您应该知道Matlab对其设计任务非常专业,并且您不太可能使用Boost来匹配它。另一方面 - Boost是免费的,而Matlab肯定不是。

我相信通过将uBlas代码绑定到底层LAPACK实现,可以获得最佳的Boost性能。

答案 1 :(得分:2)

你应该在矩阵乘法的左边使用noalias,以便摆脱不必要的副本。

而不是E = prod(A,B);使用noalias(E) = prod(A,b);

来自文档:

  

如果你肯定知道左手表情和右手   表达式没有公共存储,然后赋值没有别名。一个   在这种情况下,可以指定更有效的分配: noalias(C)=   prod(A,B); 这可以避免创建一个临时矩阵   在正常分配中需要。 'noalias'任务要求   左手边和右手边符合尺寸。

答案 2 :(得分:1)

有很多高效的BLAS实现,比如ATLAS,gotoBLAS,MKL,请改用它们。

我不选择代码,但猜测ublas :: prod(A,B)使用三个循环,没有块而不是缓存友好。如果这是真的,那么prod(A,B.trans())将比其他人快得多。

如果可以使用cblas,请使用cblas_dgemm进行计算。如果没有,你可以简单地重新排列数据,手段,prod(A,B.trans())。

答案 3 :(得分:0)

你不知道内存管理在这里扮演什么角色。 prod必须分配一个32mb的矩阵,trans也是两次,然后你做了10次。拿几个stackhots,看看真正做了什么。我的愚蠢猜测是,如果你预先分配矩阵,你会得到更好的结果。

可以加快矩阵乘法的其他方式

  • 预转置左侧矩阵,对缓存友好,

  • 跳过零。只有当A(i,k)和B(k,j)都是非零时才有任何贡献值。

这是否在uBlas中完成是任何人的猜测。