我想用一个3-D Eigen::Tensor替换代码中的一个矩阵序列。考虑到这一点,我试着比较张量和矩阵的性能。
下面的函数"tensorContractTest“执行(n,n,n)秩3张量的收缩,其中秩1张量的大小为n (n = 500)。此收缩计算n**2个点积,因此就运算数量而言,它等同于两个(n,n)矩阵的乘法(下面的函数"matrixProductTest“)。
在Visual Studio2013上运行时,函数"tensorContractTest“的运行速度比"matrixProductTest”慢约40倍。也许,我遗漏了一些东西。感谢您的帮助。
#include <unsupported/Eigen/CXX11/Tensor>
using namespace Eigen;
// Contracts 3-dimensional (n x n x n) tensor with 1-dimensional (n) tensor.
// By the number of operations, it's equivalent to multiplication of
// two (n, n) matrices (matrixProdTest).
Tensor<double, 2> tensorContractTest(int n)
{
Tensor<double, 3> a(n, n, n); a.setConstant(1.);
Tensor<double, 1> b(n); b.setConstant(1.);
auto indexPair = array<IndexPair<int>, 1>{IndexPair<int>(2,0)};
Tensor<double, 2> result = a.contract(b, indexPair);
return result;
}
MatrixXd matrixProductTest(int n)
{
MatrixXd a = MatrixXd::Ones(n, n), result = a * a;
return result;
}
发布于 2018-01-05 21:21:46
即使浮点操作的数量是相同的顺序,但存储器访问模式完全不同,因此这两个操作根本不具有可比性。一般来说,矩阵-矩阵操作总是比矩阵-向量或向量-向量操作更快(就FLOPS而言),因为前者可以实现更好的缓存使用,从而实现对CPU的ALU的近乎最佳的使用。在这种情况下,一方面必须读取一个n^3张量,而不是两个n^2矩阵,因此内存占用根本不具有可比性。
在内部,Tensor::contract
在可能的情况下会退回到Eigen的矩阵产品内核,因此性能应该是成对的。
发布于 2018-01-05 18:50:08
因为张量收缩与矩阵乘法不同。
存在用于矩阵乘法的专用算法,例如减少总运算量的Strassen算法。此外,多年来,矩阵库已经高度优化,因此它们通常根据平台(Intel、AMD、ARM)使用矢量化指令(SIMD或AVX)而进行专门化。对于小尺寸或稀疏模式的矩阵,与非专门化代码相比,速度增益是巨大的。
相反,张量库往往没有那么优化。因此,如果你可以将张量数学转化为矩阵代数,那么速度将有很多机会提高。
https://stackoverflow.com/questions/48105543
复制相似问题