私は最近、Linux 用の Intel C++ コンパイラ、Composer XE 2013 をダウンロードしてインストールしました。これは、非商用の開発に自由に使用できます。 http://software.intel.com/en-us/non-commercial-software-development
私はアイビーブリッジシステム(AVXを搭載)で実行しています。同じことを行う関数の 2 つのバージョンがあります。1 つは SSE/AVX を使用しません。他のバージョンは AVX を使用します。GCC では、AVX コードはスカラー コードよりも約 4 倍高速です。ただし、Intel C++ コンパイラを使用すると、パフォーマンスが大幅に低下します。GCCで私はこのようにコンパイルします
gcc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic
Intelでは、このようにコンパイルします
icc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic
omp_get_wtime()
この時点では、OpenMP のみをタイミング (と) に使用しています。奇妙なことに、avx オプションを変更してmsse2
、コードが GCC ではコンパイルに失敗するが、ICC では問題なくコンパイルされるということです。実際、すべてをまとめてドロップしmavx
てもコンパイルできます。どのオプションを試してもコンパイルはできますが、AVX コードを最適に使用していないようです。ICC で SSE/AVX を有効化/無効化する際に何か間違ったことをしているのだろうか?
これが私が使用しているAVXの機能です。
inline void prod_block4_unroll2_AVX(double *x, double *M, double *y, double *result) {
__m256d sum4_1 = _mm256_set1_pd(0.0f);
__m256d sum4_2 = _mm256_set1_pd(0.0f);
__m256d yrow[6];
for(int i=0; i<6; i++) {
yrow[i] = _mm256_load_pd(&y[4*i]);
}
for(int i=0; i<6; i++) {
__m256d x4 = _mm256_load_pd(&x[4*i]);
for(int j=0; j<6; j+=2) {
__m256d brod1 = _mm256_set1_pd(M[i*6 + j]);
sum4_1 = _mm256_add_pd(sum4_1, _mm256_mul_pd(_mm256_mul_pd(x4, brod1), yrow[j]));
__m256d brod2 = _mm256_set1_pd(M[i*6 + j+1]);
sum4_2 = _mm256_add_pd(sum4_2, _mm256_mul_pd(_mm256_mul_pd(x4, brod2), yrow[j+1]));
}
}
sum4_1 = _mm256_add_pd(sum4_1, sum4_2);
_mm256_store_pd(result, sum4_1);
}
これは秒単位のタイミング情報です。L1、L2、および L3 キャッシュ範囲に対応する 3 つの範囲を実行します。L1 リージョンでは 4x しか得られません。ICC のスカラー コードははるかに高速ですが、AVX コードは低速です。
GCC:
nvec 2000, repeat 100000
time scalar 5.847293
time SIMD 1.463820
time scalar/SIMD 3.994543
nvec 32000, repeat 10000
time scalar 9.529597
time SIMD 2.616296
time scalar/SIMD 3.642400
difference 0.000000
nvec 5000000, repeat 100
time scalar 15.105612
time SIMD 4.530891
time scalar/SIMD 3.333917
difference -0.000000
ICC:
nvec 2000, repeat 100000
time scalar 3.715568
time SIMD 2.025883
time scalar/SIMD 1.834049
nvec 32000, repeat 10000
time scalar 6.128615
time SIMD 3.509130
time scalar/SIMD 1.746477
nvec 5000000, repeat 100
time scalar 9.844096
time SIMD 5.782332
time scalar/SIMD 1.702444