4

有没有办法提高boost 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 次尝试的平均值。标准差小于 0.005

我希望一个因素可能是 2-3,但不是 50(!)

编辑 3:一切都在发布( NDEBUG/MOVE_SEMANTICS/.. )模式下进行。

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

4

4 回答 4

4

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

但是您应该知道,Matlab 对其设计任务高度专业化,您不太可能使用 Boost 来匹配它。另一方面 - Boost 是免费的,而 Matlab 绝对不是。

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

于 2011-10-17T19:08:19.607 回答
3

您应该noalias在矩阵乘法的左侧使用,以消除不必要的副本。

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

从文档:

如果您确定左侧表达式和右侧表达式没有公共存储,那么赋值就没有别名。在这种情况下可以指定更有效的分配:noalias(C) = prod(A, B); 这避免了创建正常分配中所需的临时矩阵。'noalias' 分配要求左右手边的大小一致。

于 2012-07-08T11:33:15.000 回答
1

有许多高效的 BLAS 实现,如 ATLAS、gotoBLAS、MKL,使用它们代替。

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

如果 cblas 可用,则使用 cblas_dgemm 进行计算。如果没有,您可以简单地重新排列数据,即 prod(A, B.trans()) 代替。

于 2011-10-28T08:43:38.960 回答
0

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

可以加速矩阵乘法的其他方法是

  • 预转置左侧矩阵,使其对缓存友好,并且

  • 跳过零。仅当 A(i,k) 和 B(k,j) 均非零时,才贡献任何值。

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

于 2011-10-17T20:43:07.110 回答