我正在为 iPhone 实现基于切线距离的 OCR 解决方案,它严重依赖于大小为 253x7 的浮点矩阵的快速乘法。为了概念验证,我实现了自己的简单矩阵例程,如下所示:
Matrix operator*(const Matrix& matrix) const {
if(cols != matrix.rows) throw "cant multiply!";
Matrix result(rows, matrix.cols);
for(int i = 0; i < result.rows; i++){
for(int j = 0; j < result.cols; j++){
T tmp = 0;
for(int k = 0; k < cols; k++){
tmp += at(i,k) * matrix.at(k,j);
}
result.at(i,j) = tmp;
}
}
return result;
}
如您所见,它非常基本。在 PoC 表现良好之后,我决定通过合并Accelerate Framework的矩阵乘法(大概使用 SIMD 和其他花哨的东西来完成繁重的工作......)进一步推动性能限制:
Matrix operator*(const Matrix& m) const {
if(cols != m.rows) throw "cant multiply!";
Matrix result(rows,m.cols);
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, rows, m.cols, cols, 1, matrix, cols, m.matrix, m.cols, 1, result.matrix, result.cols);
return result;
}
令人震惊(至少对我而言),上面的代码将矩阵相乘花费了两倍的时间!我尝试使用单精度而不是双精度,因为我怀疑它与 CPU 的字长有关(32 位浮点数与 32 位 ARM 上的 64 位双精度),但没有性能提升......
我究竟做错了什么?我的 253x7 矩阵是否太小而无法在幼稚的实现中显着提升性能?