考虑一个矩阵 A 的大小为48x16的浮点数和一个大小为1x48的浮点数 b 。
请建议在普通桌面处理器(i5 / i7)上尽快计算 b × A 。
背景 上述产品处于紧密循环中,因此其快速计算至关重要。目前我正在使用以下天真算法:
inline void Critical(const float A[48][16], const float b[48], float x[16] ) const {
for (int u = 0; u < 48; ++u) {
for (int i = 0; i < 16; ++i) {
x[i] += A[u][i] * b[u];
}
}
}
我试图将乘法卸载到MKL的SGEMV,然后卸载到SGEMM,但无济于事。在i7 4800MQ上,天真的实现仍然可以更快地运行。
EDIT1
静态分配的特征与初始算法一样快。
我尝试打开优化的GCC5,ICC和VC2015U3(/ O3,快速数学,mtune = native等)。 ICC似乎在Linux和Windows上产生了最快的代码。
EDIT2
A 的元素很小,max(| A _ui |)= 256.同样max(| b _u |)= 1.0。只要算法比天真算法快,合理的近似解也是可以接受的。
答案 0 :(得分:2)
MKL通常具有较大的开销,因此对于小矩阵而言性能较差。另一方面,Eigen具有固定大小的矩阵优化,在小矩阵上表现良好。您还需要正确的编译选项以获得Eigen的最大性能。
#include <iostream>
#include <Eigen/Eigen>
#include <omp.h>
inline void Critical(const float A[48][16], const float b[48], float x[16]) {
for (int i = 0; i < 16; ++i) {
x[i] = 0;
}
for (int u = 0; u < 48; ++u) {
for (int i = 0; i < 16; ++i) {
x[i] += A[u][i] * b[u];
}
}
}
int main() {
float a[48][16] = { 0 };
float b[48] = { 0 };
float x[16] = { 0 };
Eigen::Matrix<float, 48, 16> ma;
Eigen::Matrix<float, 1, 48> mb;
Eigen::Matrix<float, 1, 16> mx;
ma.setRandom();
mb.setRandom();
for (int i = 0; i < 48; ++i) {
for (int j = 0; j < 16; ++j) {
a[i][j] = ma(i, j);
}
b[i] = mb(i);
}
double t;
int n = 10000000;
t = omp_get_wtime();
for (int i = 0; i < n; ++i) {
Critical(a, b, x);
}
t = omp_get_wtime() - t;
std::cout << "for-loop time: " << t << std::endl;
t = omp_get_wtime();
for (int i = 0; i < n; ++i) {
mx = mb * ma;
}
t = omp_get_wtime() - t;
std::cout << "eigen time: " << t << std::endl;
Eigen::Map < Eigen::Matrix<float, 1, 16> > native_x(x);
std::cout << "error: " << (mx - native_x).norm() << std::endl;
return 0;
}
使用g ++ 5.2.1进行编译时
$ g++ -fopenmp -O3 -DNDEBUG -I~/program/include/eigen3 -o test/gemv test/gemv.cpp && test/gemv
for-loop time: 2.53004
eigen time: 1.17458
error: 1.49636e-06
使用icpc 16.0.2进行编译时
$ icpc -fopenmp -fast -DNDEBUG -I~/program/include/eigen3 -o test/gemv test/gemv.cpp && test/gemv
for-loop time: 1.03432
eigen time: 1.01054
error: 1.40769e-06
icpc在fop-loop上使用自动矢量化,因此性能与Eigen相同。