我最近下载并安装了适用于 Linux 的 Intel C++ 编译器 Composer XE 2013,可免费用于非商业开发。 http://software.intel.com/en-us/non-commercial-software-development
我在常春藤桥系统(具有 AVX)上运行。我有两个版本的函数做同样的事情。一个不使用 SSE/AVX。另一个版本使用 AVX。在 GCC 中,AVX 代码比标量代码快四倍。但是,使用英特尔 C++ 编译器时,性能要差得多。使用 GCC 我像这样编译
gcc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic
使用英特尔我这样编译
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 缓存范围。我在 L1 区域只得到 4 倍。请注意,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