![](/img/trans.png)
[英]Raw pointer, smart pointer or std::vector for “low-level” container data in C++
[英]Multiply rows of the matrix by a vector (low-level optimization)?
使用Eigen矩陣庫 ,您要做的實際上是將對角矩陣相乘。 如果您具有任意多行和20列的矩陣,則可以編寫以下內容(不值得為此編寫函數):
void multRows(Eigen::Matrix<double, Eigen::Dynamic, 20>& mat,
const Eigen::Matrix<double,20,1>& vect)
{
mat = mat * vect.asDiagonal();
}
如果編譯器啟用了Eigen,它會生成AVX2代碼。 您可能要進行實驗,如果是更高效的存儲mat
行主要或列在主要的使用情況。
附錄 (由於已編輯的問題):如果(多於)20列,則應該一起使用動態大小的矩陣:
void multRows(Eigen::MatrixXd& mat, const Eigen::VectorXd& vect)
{
mat = mat * vect.asDiagonal();
}
最近的大多數處理器都支持AVX
技術。 它提供了一個包含4個double(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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.