使用行主矩阵的特征矩阵乘法性能

Eigen matrix multiplication performance using row-major Matrices

本文关键字:性能 特征      更新时间:2023-10-16

当我遇到以下问题时,我正在分析我的代码以获得更好的性能。
下面的代码随机分配两个矩阵并将它们相乘,以不同的方式和不同的性能获得相同的结果。

#include <iostream>
#include "Eigen/Dense"
#include <chrono>
using namespace Eigen;
using namespace std;
class Timer {
protected:
std::chrono::high_resolution_clock::time_point t1_;
string message_;
public:
Timer(){t1_ = chrono::high_resolution_clock::now();}
virtual ~Timer() {}
void time(const char* msg) {
auto t2 = chrono::high_resolution_clock::now();
cerr << msg << ": "
<< chrono::duration_cast<chrono::milliseconds>(t2 - t1_)
.count() << " msn";
t1_ = t2;
}
};
typedef Matrix<float, -1, -1, RowMajor> MatrixXRMf;
int main(int argc, char** argv) {
Timer timer;
MatrixXf A = MatrixXf::Random(10, 4096);
MatrixXf B = MatrixXf::Random(4096, 10000);
timer.time("random");
MatrixXf C1 = A * B;
timer.time("col-maj 1");
MatrixXf C2 = (B.transpose() * A.transpose());
C2.transposeInPlace();
timer.time("col-maj 2");

MatrixXRMf A_rm = A;
MatrixXRMf B_rm = B;
timer.time("assignment");
MatrixXRMf C3 = A_rm * B_rm;
timer.time("row-maj 1");
MatrixXRMf C4 = (B_rm.transpose() * A_rm.transpose());
C4.transposeInPlace();
timer.time("row-maj 2");
cout << "C3 == C1: " << C3.isApprox(C1) << endl;
return 0;
}

打印结果为

random: 352 ms
col-maj 1: 130 ms
col-maj 2: 72 ms
assignment: 981 ms
row-maj 1: 62 ms
row-maj 2: 80 ms
C3 == C1: 1

为什么 C1 乘法比 C3 慢? 如果多次执行 C1 乘法,可能会导致严重的性能损失。

特征:3.3.4
编译器:GCC 5.4
操作系统:Ubuntu16

编辑: 编译标志: -O3 -mavx -mfma -fopenmp

编辑: 我有两台 ubuntu16 机器可以重现此行为 和另一台不复制它的 Ubuntu16 机器

我得到完全不同的结果,OSX,2.6Ghz Haswell(trubo-boost off(:

# gcc-7 -O3  -mavx -mfma
random: 498 ms
col-maj 1: 26 ms
col-maj 2: 69 ms
assignment: 674 ms
row-maj 1: 50 ms
row-maj 2: 57 ms
# Apples's clang 8 -O3  -mavx -mfma
random: 478 ms
col-maj 1: 25 ms
col-maj 2: 66 ms
assignment: 666 ms
row-maj 1: 55 ms
row-maj 2: 75 ms

使用RowVectorXf后(或VectorXf( 表示AC1A_rmC3(或C2C4(,并删除无用的transposeInPlace,我得到:

# Apples's clang 8 -O3  -mavx -mfma
random: 472 ms
col-maj 1: 12 ms
col-maj 2: 11 ms
assignment: 673 ms
row-maj 1: 13 ms
row-maj 2: 11 ms

编辑:使用编辑过的问题(例如,A = MatrixXf::Random(10, 4096);(后,我仍然无法重现,即使使用gcc-5,如问题中所示:

random: 482 ms
col-maj 1: 60 ms
col-maj 2: 80 ms
assignment: 676 ms
row-maj 1: 79 ms
row-maj 2: 85 ms