2014-02-10 9 views
3

나는 현재 프로그램을 벡터화하기 위해 노력하고 그리고 난pragma simd와 ivdep vector의 차이점은 언제나?

의 #pragma SIMD

(262)를 사용할 때

가 for 루프가 벡터화 것 같다 이상한 행동을 관찰 : (골을. 3) remark : SIMD LOOP가 VECTORIZED되었습니다.

하지만 난 항상

가의 #pragma ivdep이

(262)

의 #pragma 벡터를 사용하지 않을 때 수행합니다. (COL 3) 비고 : 루프가 벡터화되지 않았습니다 : 벡터 의존성의 존재.

난 항상 두 문장에 관계없이 비용이나 안전,

답변

4

프라 그마 SIMD 루프의 벡터화를 적용하는 동일한 벡터화을 생각했다.

pragma vector는 벡터 라이 제이션 여부를 결정할 때 항상 컴파일러에서 효율성 추론을 무시하도록 지시합니다. 이 pragma가 추가 될 때만 벡터화되는 코드는 느려질 수 있습니다.

pragma ivdep는 벡터화를 금지하는 가정 된 데이터 종속성 (예 : 루프 전달 종속성)은 무시하지만 컴파일러는 검증 된 데이터 종속성을 무시하도록 컴파일러에 지시합니다. 예를 들어, 포인터가 동일한 메모리를 가리키고 벡터화한다고 가정 할 수 있습니다. 그러나, 그것은 입증 된 루프 종속 의존성을 무시하지 않을 것이다 (a [i] = a [i - 1] * c). 그러나 pragma simd는 그렇다.

코드가 프라그 마에서만 벡터화 된 이유는 입증 된 의존도가 무시되었습니다. 프로그램 출력이 정확한지 확인하는 것이 좋습니다.

출처 : 인텔 관련 pragma 문서 (http://software.intel.com/en-us/node/462880) 프라 그마 벡터 컴파일러를 표시하는 데 사용되는 도구입니다 동안

2

에서 Pragma SIMD가 https://software.intel.com/en-us/node/514582에서 언급 한 바와 같이 벡터화를 시행 할 수있는 개발자에게 주어진 명시 적 벡터화 도구입니다 루프 그 인수에 따라 벡터화되어야합니다. 여기서 인수는 항상 "컴파일러의 비용/효율성 추론을 무시하고 벡터화를 진행해야 함"을 의미합니다. 프라그마 벡터에 대한 자세한 내용은 https://software.intel.com/en-us/node/514586에서 확인할 수 있습니다. 이것은 pragma 벡터가 항상 벡터화되지 못할 때 pragma simd가 잘못된 결과를 생성한다는 것을 의미하지 않습니다. #pragma simd를 올바른 절 집합과 함께 사용하면 벡터화되어 올바른 결과를 얻을 수 있습니다.

void foo(float *a, float *b, float *c, int N){ 
    #pragma vector always 
    #pragma ivdep 
    //#pragma simd vectorlength(2) 
    for(int i = 2; i < N; i++) 
     a[i] = a[i-2] + b[i] + c[i]; 
    return; 
    } 

다음 벡터화 보고서를 생성합니다 ICC를 사용하여이 코드를 컴파일 :

$ icc -c -vec-report2 test11.cc 
test11.cc(5): (col. 1) remark: loop was not vectorized: existence of vector dependence 

128 비트 XMM 레지스터를 사용하여 기본 ICC 대상으로 SSE2 아래의 것을 보여줍니다 작은 코드 조각입니다. 하나의 XMM 레지스터에는 4 개의 부동 소수점을 수용 할 수 있지만 4 개의 부동 소수점 벡터를 수용하려고하면 벡터 의존성이 있습니다. 그래서 #pragma vector가 항상 내보내는 것이 옳다. 그러나 4 대신에 2 개의 float 만 고려하면 결과를 손상시키지 않고이 루프를 벡터화 할 수 있습니다.같은 대한 벡터화 보고서는 다음과 같습니다 :

void foo(float *a, float *b, float *c, int N){ 
//#pragma vector always 
//#pragma ivdep 
#pragma simd vectorlength(2) 
for(int i = 2; i < N; i++) 
     a[i] = a[i-2] + b[i] + c[i]; 
return; 
} 
$ icc -c -vec-report2 test11.cc 
test11.cc(5): (col. 1) remark: SIMD LOOP WAS VECTORIZED 

그러나의 #pragma 벡터 명시 적으로 동안 루프 벡터링 고려하는 벡터 길이를 지정할 수 있습니다 절을하지 않습니다. 이것은 simd가 정말로 유용 할 수있는 pragma이었다. 벡터 방식으로 계산을 가장 잘 설명하는 right 절과 함께 사용할 때 컴파일러는 잘못된 결과를 생성하지 않는 요청 된 벡터를 생성합니다. https://software.intel.com/sites/default/files/article/402486/intel-cilk-plus-white-paper.pdf에 게시 된 Intel (R) Cilk (TM) Plus 백서에는 "$ pragma simd vectorlength 절 사용"절과 "$ pragma simd reduction 및 private 절 사용법"절이 있습니다.이 절에서는 오른쪽 절과 함께 simd 절을 작성하는 방법을 설명합니다 . 이 절은 개발자가 컴파일러에게 달성하고자하는 것을 표현하는 데 도움을 주며 컴파일러는 이에 따라 벡터 코드를 생성합니다. 컴파일러에 루프 논리를 가장 잘 표현할 필요가있는 곳에는 관련 절이있는 #pragma simd를 사용하는 것이 좋습니다.

또한 내부 루프는 벡터화 대상이지만 pragma simd는 외부 루프 벡터화에도 사용할 수 있습니다. 자세한 내용은 https://software.intel.com/en-us/articles/outer-loop-vectorization에서 확인할 수 있습니다.

+0

'for' 루프의 시작 인덱스는'i = 2'이어야한다고 생각합니다 ... –