C/C++中简单快速的矩阵矢量乘法
Simple and fast matrix-vector multiplication in C / C++
我需要经常使用matrix_vector_mult()
,它将矩阵与向量相乘,下面是它的实现。
问题:有没有一种简单的方法可以让它显著地、至少快两倍
备注:1)矩阵尺寸约为300x50。在跑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),通过手动展开4次乘法运算(每个矩阵大约18us,而不是每个矩阵34us),在300x50矩阵上获得了大约两倍的速度:
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;
}
然而,我预计这种级别的微观优化的结果在不同系统之间会有很大的差异。
正如真亚所说,只要使用一个好的BLAS或矩阵数学库。
如果由于某种原因你不能做到这一点,看看你的编译器是否可以展开和/或向量化你的循环;如果您发布的函数可用于内联,那么确保行和列在调用站点都是常量可能会有所帮助
如果您仍然无法获得所需的加速,您可以考虑手动展开,并使用扩展或内联汇编程序进行矢量化。
如果大小是常量并且事先已知,请将其作为预编译器变量传入,这将允许编译器进行更充分的优化。
相关文章:
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- C++-字符串是否包含一个带有简单循环的单词
- 关于 c++ 函数中指针赋值的简单问题
- 从函数返回任意简单类型的数据
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 当简单捕获中的标识符显示为参数的声明符 ID 时,没有编译器诊断
- 如何使用 samtools C API 构建一个简单的主.cpp文件
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法