8

以下を使用して、SSEとAVXの両方で行列ベクトル乗算を作成していました。

for(size_t i=0;i<M;i++) {
    size_t index = i*N;
    __m128 a, x, r1;
    __m128 sum = _mm_setzero_ps();
    for(size_t j=0;j<N;j+=4,index+=4) {
         a = _mm_load_ps(&A[index]);
         x = _mm_load_ps(&X[j]);
         r1 = _mm_mul_ps(a,x);
         sum = _mm_add_ps(r1,sum);
    }
    sum = _mm_hadd_ps(sum,sum);
    sum = _mm_hadd_ps(sum,sum);
    _mm_store_ss(&C[i],sum);
}

AVX にも同様の方法を使用しましたが、最後に、AVX には と同等の命令がないため_mm_store_ss()、以下を使用しました。

_mm_store_ss(&C[i],_mm256_castps256_ps128(sum));

SSE コードは、シリアル コードよりも 3.7 高速化されています。ただし、AVX コードは、シリアル コードよりも 4.3 高速化するだけです。

AVX で SSE を使用すると問題が発生する可能性があることはわかっていますが、g++ を使用して -mavx' フラグを付けてコンパイルし、SSE オペコードを削除する必要があります。

:_mm256_storeu_ps(&C[i],sum)を使用して同じことを行うこともできますが、スピードアップは同じです。

パフォーマンスを向上させるために他に何ができるかについての洞察はありますか? 関連できますか : performance_memory_bound、そのスレッドの答えを明確に理解していませんでした。

また、ヘッダーファイル「immintrin.h」をインクルードしても_mm_fmadd_ps()命令が使えません。FMA と AVX の両方を有効にしています。

4

4 に答える 4

-2

繰り返しになりますが、独自の行列乗算アルゴリズムを構築する場合は、停止してください。Intel の AVX フォーラムで、インテルのエンジニアの 1 人が、2 つの行列 (特に小さな行列)を乗算するための AVX の理論上のスループットに到達するまでに、AVX アセンブリを作成するのに非常に長い時間がかかったと告白したことを覚えています。並列バージョンのスレッド オーバーヘッドを克服するのが難しいことは言うまでもありません。

Intel Math Kernel Libraryをインストールし、30 分かけてマニュアルを読み、ライブラリを呼び出す 1 行をコーディングしてください

于 2015-01-19T13:30:41.737 に答える