1

C で行列乗算プログラムを最適化しています。現在、私のコードは次のようになっています。

最初に、マトリックスの構造体があります。

typedef struct
{
    float ** element;
} matrix;

次に、行列乗算ルーチンを作成し、2 番目の行列を転置して simd を使用して最適化しました。

void mulMatrices(matrix a, matrix b, matrix result)
{

    int i, j, k;
    long long before, after;

    before = wall_clock_time();

    transpose_matrix(&b);

    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
        {
            __m128 vresult = _mm_setzero_ps();
            for(k = 0; k < size; k += 4)
            {
                vresult = _mm_add_ps(vresult, _mm_mul_ps(_mm_load_ps(&(a.element[i][k])), _mm_load_ps(&(b.element[j][k]))));
            }
            result.element[i][j] = vresult[0] + vresult[1] + vresult[2] + vresult[3];
        }

    after = wall_clock_time();
}

最後に、行列を初期化し、乗算関数を呼び出すワーカー関数を作成しました

void work()
{
    matrix a, b, result;

    // Initialise matrices

    // Perform sequential matrix multiplication
    mulMatrices(a, b, result);

    // Print the result matrix
    //print_matrix(result);

}

私の主な機能は次のようになります。

int main(int argc, char ** argv)
{   
    // Multiply the matrices
    work();
    return 0;
}

私はすでにこれらのものでかなり満足のいく結果を達成することができました. しかし、すべてを合理化し、すべてのコードをメイン関数に移動すると、100 倍以上高速になることがわかりました。行列のサイズは少なくとも 1024 * 1024 です。コールスタックに関係があると思いますが、わかりません。誰か説明してくれませんか。ありがとう

4

1 に答える 1

1

エイリアシングの問題が発生している可能性があります。基本的に、ポインターを介して値を編集する場合、コンパイラーは、既に読み取ったものを変更したかどうかを認識できないため、毎回メモリから値を再読み取りする必要があります。

問題を説明するホワイトペーパーは次のとおりです: ftp://ftp.sgi.com/sgi/audio/audio.apps/dev/aliasing.html

すべてのコードをメインに直接移動することで、エイリアスを削除したため、パフォーマンスが大幅に向上しました。

于 2013-10-04T19:00:44.100 に答える