에서 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에서 확인할 수 있습니다.
'for' 루프의 시작 인덱스는'i = 2'이어야한다고 생각합니다 ... –