以下を使用して、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 の両方を有効にしています。