为何利用矩阵结构的稀疏矩阵-向量乘积代码比朴素版慢50%?
稀疏矩阵-向量乘积优化问题
我正在优化C++稀疏线性系统相关代码,目标是实现高效的稀疏矩阵-向量乘积。
初始实现与性能表现
首先实现了不利用矩阵结构的朴素版本:
struct triplet { unsigned int i; unsigned int j; float val; }; typedef std::vector<triplet> matrix; typedef std::vector<float> vector; void naiveMatMul(const matrix & A,const vector & B, vector & result) { for(auto & coef : A) { result[coef.i] += coef.val * B[coef.j]; } }
该版本处理含约100k系数的矩阵,完成3000次乘积耗时约200ms。
由于已知该稀疏系统的行分为两类:一类含8个系数,另一类含2个系数,我又实现了利用该结构的packed版本:
struct packedMatrix { struct packedCoef{unsigned int col; float val;}; std::vector<packedCoef> coefs; unsigned int row_8; unsigned int row_2; }; void packedMatMul( const packedMatrix &A, const vector &B, vector & result) { unsigned int currentLine=0; unsigned int currentCoefIdx = 0; while(currentLine<A.row_8) { for(int i=0;i<8;i++) { result[currentLine] += A.coefs[currentCoefIdx].val * B[A.coefs[currentCoefIdx].col]; currentCoefIdx++; } currentLine++; } while(currentLine<A.row_2) { for(int i=0;i<2;i++) { result[currentLine] += A.coefs[currentCoefIdx].val * B[A.coefs[currentCoefIdx].col]; currentCoefIdx++; } currentLine++; } }
但该版本不仅未提速,反而慢了约50%(耗时约300ms)。原本以为按行分组的结构能帮助编译器自动向量化,但查看汇编后发现朴素版的代码更简洁。
后续修改与未解决问题
之后根据建议做了两处修改:
- 使用
-ffast-math编译选项(Visual Studio中对应/fp:fast) - 在内部循环中使用临时累加器,计算完成后再赋值给
result[currentLine]
修改后在汇编查看工具中能看到向量化的汇编代码,但在Visual Studio中启用/fp:fast选项后,运行耗时仍无改善,希望了解问题所在。
内容的提问来源于stack exchange,提问作者Roco Le Coquelicot
相关产品推荐
相关产品推荐

