簡體   English   中英

如何在 C++ 中編寫矩陣乘法的快速代碼?

[英]How to write fast code for matrix multiplication in C++?

我為矩陣乘法編寫了一些 C++ 代碼。 我使用vector<double>來保存矩陣條目,並使用一系列 3 個嵌套的for循環來逐項計算乘法。 事實證明,這非常慢(對於 900*500 和 500*500 矩陣乘法,在我的 macbook air 上大約需要 10 秒)。 是什么原因? 我是否使用了錯誤的矩陣表示或者代碼中有很大的缺陷?

    for (int c_b=0;c_b<B.n_c;c_b++)
    {
        vector<double> vtmp(A.n_r);
        for (int r_a=0;r_a<A.n_r;r_a++)
        {
            sum=0;
            for (int i=0;i < A.n_c;i++)
            {
                sum=sum+A.mat[r_a+i*A.n_r]*B.mat[i+c_b*B.n_r];
            }
            vtmp[r_a]=sum;
        }
        Cvv[c_b]=vtmp;
    }

更新:此問題已通過在 Lapack 中使用子程序解決。

下面是一些性能改進的建議。

將 Vector 移出循環
矢量的創建需要時間。 在任何 for 循環之前移動聲明:

vector<double> vtmp(A.n_r);
for (int c_b=0;c_b<B.n_c;c_b++)
{
    for (int r_a=0;r_a<A.n_r;r_a++)
    {
        //...
    }
}

剖析分配計算。
沒有任何分析或基准測試,賦值語句看起來占用的時間最多。 將其分解為單獨的步驟以幫助編譯器,因此您可以查看是否可以更優化地執行計算。
原來的:

sum=sum+A.mat[r_a+i*A.n_r]*B.mat[i+c_b*B.n_r];

解剖[1]:

const int A_Index = r_a + i * A.n_r;
const int B_Index = i + c_b*B.n_r;
sum = sum + A.mat[A_Index] * B.mat[B_Index];

解剖[2](使用更多變量):

const int temp1 = i * A.n_r;
const int temp2 = c_b * B.n_r;
const int A_Index = r_a + temp1;
const int B_Index = i + temp2;
sum = sum + A.mat[A_Index] * B.mat[B_Index];

以上可以幫助編譯器選擇最佳處理器指令。

使用局部變量
理想情況下,您希望處理器從矩陣中獲取盡可能多的連續位置,同時它在重新加載之前位於數據緩存中 像這樣的東西:

int ATemp1 = A[w];
int ATemp2 = A[x];
int ATemp3 = A[y];
int ATemp4 = A[z];

int BTemp1 = B[e];
int BTemp2 = B[f];
int BTemp3 = B[g];
int BTemp4 = B[h];

sum = sum + ATemp1 * BTemp1;
sum = sum + ATemp2 * BTemp2;
sum = sum + ATemp3 * BTemp3;
sum = sum + ATemp4 * BTemp4;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM