有没有办法提高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: 产品结果的预分配矩阵不会影响运行时间。
答案 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中完成是任何人的猜测。