将矩阵的行乘以向量(低级优化)
Multiply rows of the matrix by a vector (low-level optimization)?
我正在优化一个函数,我想摆脱缓慢的循环。我正在寻找一种更快的方法来将矩阵的每一行乘以向量。
我不是在寻找"经典"乘法。
例如。我有一个矩阵,具有1024列和20行,一个向量为1024。
我现在在做什么,我在矩阵行的for循环中迭代并使用mkl V?mul通过当前矩阵行和向量的元素乘法执行元素。有什么想法如何改进?
问题是矩阵的复制行乘乘以向量吗? 但是对于可能具有低级优化和MKL的C ,而不是R
使用eigen矩阵库,您正在使用的是乘以对角线矩阵。如果您有一个任意的许多行和20列的矩阵,则可以编写以下内容(实际上不值得为此发挥作用):
void multRows(Eigen::Matrix<double, Eigen::Dynamic, 20>& mat,
const Eigen::Matrix<double,20,1>& vect)
{
mat = mat * vect.asDiagonal();
}
如果编译器启用了AVX2代码,则 eigen确实会生成AVX2代码。如果您的用例更有效地存储mat
行专业或专栏专业,则可能需要实验。
附录(由于已编辑的问题):如果您(大多数)超过20列,则应仅使用动态尺寸的矩阵:
void multRows(Eigen::MatrixXd& mat, const Eigen::VectorXd& vect)
{
mat = mat * vect.asDiagonal();
}
最近的大多数处理器支持AVX
技术。它提供了一个包含4个双打(256位寄存器)的向量。因此,该优化的解决方案可能使用AVX。为此,我已经使用x86intrin.h
库(是GCC
编译器的一部分)实现了它。我还使用OpenMP
使解决方案多线程。
//gcc -Wall -fopenmp -O2 -march=native -o "MatrixVectorMultiplication" "MatrixVectorMultiplication.c"
//gcc 7.2, Skylake Corei7-6700 HQ
//The performance improvement is significant (5232 Cycle in my machine) but MKL is not available to test
#include <stdio.h>
#include <x86intrin.h>
double A[20][1024] __attribute__(( aligned(32))) = {{1.0, 2.0, 3.0, 3.5, 1.0, 2.0, 3.0, 3.5}, {4.0, 5.0, 6.0, 6.5,4.0, 5.0, 6.0, 6.5},{7.0, 8.0, 9.0, 9.5, 4.0, 5.0, 6.0, 6.5 }};//The 32 is for 256-bit registers of AVX
double B[1024] __attribute__(( aligned(32))) = {2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0 }; //the vector
double C[20][1024] __attribute__(( aligned(32)));//the results are stored here
int main()
{
int i,j;
__m256d vec_C1, vec_C2, vec_C3, vec_C4;
//begin_rdtsc
//get the start time here
#pragma omp parallel for
for(i=0; i<20;i++){
for(j=0; j<1024; j+=16){
vec_C1 = _mm256_mul_pd(_mm256_load_pd(&A[i][j]), _mm256_load_pd(&B[j]));
_mm256_store_pd(&C[i][j], vec_C1);
vec_C2 = _mm256_mul_pd(_mm256_load_pd(&A[i][j+4]), _mm256_load_pd(&B[j+4]));
_mm256_store_pd(&C[i][j+4], vec_C2);
vec_C3 = _mm256_mul_pd(_mm256_load_pd(&A[i][j+8]), _mm256_load_pd(&B[j+8]));
_mm256_store_pd(&C[i][j+8], vec_C3);
vec_C4 = _mm256_mul_pd(_mm256_load_pd(&A[i][j+12]), _mm256_load_pd(&B[j+12]));
_mm256_store_pd(&C[i][j+12], vec_C4);
}
}
//end_rdtsc
//calculate the elapsead time
//print the results
for(i=0; i<20;i++){
for(j=0; j<1024; j++){
//printf(" %lf", C[i][j]);
}
//printf("n");
}
return 0;
}
相关文章:
- C++数组与向量排序(在我的情况下,向量比数组慢~2.5倍(无优化))
- 优化 c++ 数组和向量
- c++优化地返回结构和向量
- 优化将标准::uint32_t插入到标准::向量<char>中
- 如何在C++中找到两个向量之间的最小(优化)距离
- 将矩阵的行乘以向量(低级优化)
- 具有单位向量约束的非线性优化
- 如何优化C++逐行读取文件到向量中
- 如何优化这个处理大型 c++ 向量的函数
- 返回值优化与大向量的auto_ptr
- 优化向量赋值 c++
- 为指针向量优化对new的调用
- std::向量类,优化为容纳少量项
- c++,类,向量,优化:多个独立向量vs一个类向量
- 优化可变与不可变向量数学
- 优化检查一个比特向量是否是另一个的适当子集
- 如何在c++中优化检查向量中的元素
- 循环两个不同长度的向量时的优化
- 对象向量的优化向量似乎很慢
- 对向量的c++ operator()优化