2013-06-10 4 views
4

비 상업용 개발에 사용할 수있는 Linux 용 인텔 C++ 컴파일러 인 Composer XE 2013을 최근에 다운로드하여 설치했습니다. http://software.intel.com/en-us/non-commercial-software-development인텔 C++ 컴파일러 인 ICC가 SSE/AVX 시음을 내고있는 것 같습니다.

아이비 브리지 시스템 (AVX가 있음)에서 실행 중입니다. 나는 같은 일을하는 두 가지 버전의 함수를 가지고있다. 하나는 SSE/AVX를 사용하지 않습니다. 다른 버전은 AVX를 사용합니다. GCC에서 AVX 코드는 스칼라 코드보다 약 4 배 빠릅니다. 그러나 인텔 C++ 컴파일러를 사용하면 성능이 훨씬 떨어집니다. 인텔은이

gcc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic 

나는이 시점에서 (omp_get_wtime() 포함) 타이밍 난 단지 OpenMP를 사용하고이

icc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic 

처럼 컴파일처럼 GCC와 나는 컴파일합니다. 이상한 점은 내가라고 말하는 avx 옵션을 변경하면 코드가 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 

답변

1

두 지점 :

(1) 당신이 당신의 코드에서 인텔 내장 함수를 사용하고 표시 - g ++ 및 ICPC 반드시 같은 내장 함수를 구현하는 (그러나 대부분이 중복)하지 않습니다. 가져올 필요가있는 헤더 파일을 확인하십시오 (g ++에서는 inartistic을 정의하기위한 힌트가 필요할 수 있습니다). g ++에서 오류가 발생하면 오류 메시지가 나타 납니까?

(2) 플래그 지침 (ICPC --help에서) 생성되는 것은 아닙니다 할 컴파일러 : -msse3 May generate Intel(R) SSE3, SSE2, and SSE instructions

이러한 플래그는 보통 그냥 컴파일러 힌트. -xHost와 -fast를보고 싶을 수도 있습니다.

내가 컴파일하려고 시도한 옵션은 상관 없지만 AVX 코드를 최적으로 사용하지는 않습니다.

어떻게 체크 했습니까? 다른 병목 현상 (예 : 메모리 대역폭)이있는 경우 4 배 속도 향상을 볼 수 없습니다. (질문 편집 기준)

편집 : ICC 스칼라는 GCC 스칼라보다 빠른처럼

같습니다 - ICC는 스칼라 코드를 벡터화하는 것으로 보인다. 이 경우 벡터화를 수동으로 코딩 할 때 icc에서 4 배의 속도 향상을 기대하지는 않습니다.

icc와 5.782332s의 차이와 3.509130s의 gcc (nvec 5000000의 경우) 사이의 차이점. 이것은 예상치 못한 일입니다. 두 컴파일러 사이의 런타임에 차이점이있는 이유에 대한 정보를 기반으로 말할 수 없습니다.두 컴파일러에서 방출 된 코드 (http://www.delorie.com/djgpp/v2faq/faq8_20.html)를 살펴 보는 것이 좋습니다. 또한 측정 값을 재현 할 수 있는지 확인하십시오 (예 : 멀티 소켓 머신의 메모리 레이아웃, 핫/콜드 캐시, 백그라운드 프로세스 등).

+0

의견 주셔서 감사합니다. 나는 "#include "을 포함하고있다. GCC는 예를 들어 -mavx를 사용하지 않으면 "__m256d '가이 범위에서 선언되지 않았습니다. 나는 -xHost -fast-xavx를 시도했다. 아무런 차이가 없습니다. 인텔 컴파일러의 무료 버전으로 CPU 디스패처에 대해 궁금해지기 시작했습니다. 비교할 정식 버전이 없습니다. –

+0

FAQ에 따르면 상업용 버전과 동일한 기능이 포함되어있어 문제가 될 가능성이 적습니다. "비상업적 인 제품과 상용 제품간에 기능이 다릅니 까? 현재 비상업적 제품에는 상용 제품과 동일한 기능이 있습니다." http://software.intel.com/en-us/articles/non-commercial-software-faq/#7 –

+0

"GCC는"-mavx를 사용하지 않으면 "이 범위에서"__m256d '가 선언되지 않았다고 말합니다. " 플래그를 전달하지 않으면 gcc가 내장 함수를 정의하지 않는다는 것을 의미합니다. – hazydev