C / C ++中简单快速的矩阵向量乘法

我需要频繁使用matrix_vector_mult() ,它将矩阵与向量相乘,下面是它的实现。

问题:是否有一种简单的方法可以使其显着,至少两倍,更快?

备注:1)矩阵的大小约为300×50。 它在运行期间不会改变。 2)它必须适用于Windows和Linux。

 double vectors_dot_prod(const double *x, const double *y, int n) { double res = 0.0; int i; for (i = 0; i < n; i++) { res += x[i] * y[i]; } return res; } void matrix_vector_mult(const double **mat, const double *vec, double *result, int rows, int cols) { // in matrix form: result = mat * vec; int i; for (i = 0; i < rows; i++) { result[i] = vectors_dot_prod(mat[i], vec, cols); } } 

理论上这是一个好的编译器本身就应该做的事情,但是我用我的系统(g ++ 4.6.3)试了一下,并且在300×50矩阵上用大约两倍的速度展开4次乘法(每个矩阵大约18us而不是每个矩阵34us):

 double vectors_dot_prod2(const double *x, const double *y, int n) { double res = 0.0; int i = 0; for (; i <= n-4; i+=4) { res += (x[i] * y[i] + x[i+1] * y[i+1] + x[i+2] * y[i+2] + x[i+3] * y[i+3]); } for (; i < n; i++) { res += x[i] * y[i]; } return res; } 

然而,我期望这种微观优化水平的结果在系统之间变化很大。

正如Zhenya所说,只需使用一个好的BLAS或矩阵数学库。

如果由于某种原因你不能这样做,看看你的编译器是否可以展开和/或向量化你的循环; 假设您发布的函数可用于内联,确保都是调用站点的常量可能会有所帮助

如果您仍然无法获得所需的加速,那么您将看到手动展开,并使用扩展或内联汇编器进行矢量化。

如果大小是常量并且事先已知,则将其作为预编译器变量传递,这将允许编译器更充分地进行优化。