2012-07-16 6 views
11

지금까지 특정 응용 프로그램을 벡터 라이징하는 데 어려움을 겪었으며 모든 것을 시도했습니다. 자동 권한 부여에서 수작업으로 작성된 SSE 내장 함수에 이르기까지 하지만 어떻게 든 스텐실 기반 애플리케이션의 속도를 향상시킬 수 없습니다.다음 코드 조각이 벡터화되지 않은 이유를 찾을 수 없습니다.

다음은 SSE 내장 함수를 사용하여 벡터화 한 현재 코드의 스 니펫입니다. 컴파일 할 때 (Intel icc) -vec-report3을 사용하면 다음 메시지가 계속 나타납니다.
설명 : 루프가 벡터화되지 않았습니다. 문을 벡터화 할 수 없습니다.

#pragma ivdep 
    for (i = STENCIL; i < z - STENCIL; i+=4) 
    { 
    it = it2 + i; 

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k])),X4_i); //loop was not vectorized: statement cannot be vectorized 
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k])),X3_i); 
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k])),X2_i); 
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j +k*it_k])),X1_i); 

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)), _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i)); 

    _mm_store_ps(&tmp2[i],tmp6); 

    } 

오전 나는 중요한 뭔가가? 메시지가 벡터화 될 수없는 이유에 대해 정교하지 못하기 때문에 병목 현상을 확인하는 것이 어려워졌습니다.

업데이트 : 제안을 신중하게 고려한 후에 다음과 같이 코드를 수정했습니다. 나는 벡터 의존성에 실제로 책임이있는 진술을 확인하기 위해 그것을 더 세분화하는 것이 최선이라고 생각했다. 나는 (ICC) 나는 다음과 같은 메시지가 #pragma ivdep없이 위의 코드를 컴파일 할 때

//#pragma ivdep 
    for (i = STENCIL; i < z - STENCIL; i+=4) 
    { 
    it = it2 + i; 
    __m128 center = _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i); 

    u_j4 = _mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]); //Line 180 
    u_j3 = _mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]); 
    u_j2 = _mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]); 
    u_j1 = _mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]); 
    u_j8 = _mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k]); 
    u_j7 = _mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k]); 
    u_j6 = _mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k]); 
    u_j5 = _mm_load_ps(&p2[i+j*it_j+it_j +k*it_k]); 

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(u_j4,u_j8),X4_i); 
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(u_j3,u_j7),X3_i); 
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(u_j2,u_j6),X2_i); 
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(u_j1,u_j5),X1_i); 

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)); 
    __m128 tmp7 = _mm_add_ps(tmp6,center); 

    _mm_store_ps(&tmp2[i],tmp7); //Line 196 

    } 

다음 #pragma ivdep

remark: loop was not vectorized: existence of vector dependence. 
vector dependence: assumed FLOW dependence between tmp2 line 196 and tmp2 line 196. 
vector dependence: assumed ANTI dependence between tmp2 line 196 and tmp2 line 196. 

내가 컴파일 할 때 (ICC)가, 다음과 같은 메시지가 뜹니다 :

remark: loop was not vectorized: unsupported data type. //Line 180 

왜 196 행에 대한 의존성이 제안 되었습니까? 제안 된 벡터 의존성을 제거하려면 어떻게해야합니까?

+0

최종 값과 루프 수를 미리 계산하여 'for'구문을 단순화하십시오. –

+0

이미 벡터화했기 때문에 벡터화 할 수 없습니다. 계산/메모리 액세스 비율이 너무 낮기 때문에 속도가 향상되지 않습니다. – Mysticial

+0

첫 번째 생각 (Mysticial corrected me)은 정렬이 아니지만 배열 오프셋에 대한 표현식을 단순화하여 시작하는 것이 좋습니다. –

답변

2

문제는 자동 벡터화를 손으로 벡터화 된 코드와 함께 사용하려고한다는 것입니다. 컴파일러에서는 벡터 함수를 벡터화 할 수 없기 때문에 벡터화 할 수 없다고 말합니다.

컴파일러에서 자동 벡터화하거나 자동 벡터화를 사용하지 않도록 설정하고 코드를 수동으로 벡터화합니다. 이미 설명했듯이 자동 벡터 라이저는 벡터화 수익성을 계산합니다. 코드를 벡터화 할 가치가 있는지 여부를 확인합니다.