簡體   English   中英

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)試了一下,並且在300x50矩陣上用大約兩倍的速度展開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或矩陣數學庫。

如果由於某種原因你不能這樣做,看看你的編譯器是否可以展開和/或向量化你的循環; 確保行列 都在調用點可以幫助雙方常數,假設您發布的功能,可用於內聯

如果您仍然無法獲得所需的加速,那么您將看到手動展開,並使用擴展或內聯匯編器進行矢量化。

如果大小是常量並且事先已知,則將其作為預編譯器變量傳遞,這將允許編譯器更充分地進行優化。

暫無
暫無

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

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