2012-10-30 4 views
2

다음 for 루프가 있습니다. 형식 배열을 켜면 코드가 벡터화되지 않습니다. 형식을 '1'로 고칠 때 gcc는 벡터화를 소급화하는 벡터화를 수행합니다. 누구나 어떤 종류의 벡터화를 유발할 수있는 어떠한 권고안이 있습니까?내부 if 문이 벡터화를 중단합니다.

#define type(M,N) type[(M)*sizeX + (N)] 
for (int i = 0; i < sizeY - 1; i++) 
{ 
    for (int j = 0; j < sizeX - 1; j++) 
    { 
     const int id = type(i, j); 
     //const int id = 1; //vectorizes 
     const float A = this->A[id]; 
     const float B = this->B[id]; 
     a(i, j) = A * a(i, j) + B * (b(i, j) - b(i + 1, j))*(p[i]); 
    } 
} 

4.7.1

45: not vectorized: not suitable for gather A_26 = *D.14145_25; 

편집 한

하는 모든 배열은 포인터로 저장됩니다 일부 클래스의 멤버로 키워드를 제한 으로 정의 된 GCC에서 대략적인 오류 . 'type은'작은 경우 내가 할 수있는 일이

편집 2

있습니까?

편집 3

작은 8.

+0

음,'type()'은 무엇입니까? – Mysticial

+0

type은 (모든 배열과 마찬가지로) __restrict__ 키워드가있는 클래스에 정의 된 정수 배열입니다. – Mikhail

+0

함수처럼 'type()'을 호출합니다.그 기능의 정의를 보여줄 수 있습니까? – Mysticial

답변

4

차이가 메모리 액세스 수단이다.

id = 1 일 때 다음 배열로드는 단일 요소 벡터 브로드 캐스트가됩니다.

const float A = this->A[id]; 
const float B = this->B[id]; 

그러나 id = type[(i)*sizeX + (k)] 인 경우 메모리 액세스가 스트라이드 (인접하지 않음)됩니다.

  1. 연속 메모리 블록 : SSE와 AVX의

    벡터로드 및 저장 만에 수행 할 수 있습니다.

  2. 또는 전체 벡터로 브로드 캐스팅되는 단일 요소에서.

다른 메모리 부분의 각 벡터 요소를로드 할 때 스트라이드 된 메모리 액세스를 처리 할 수 ​​없습니다.

AVX2는 이러한 "수집/분산"지침을 지원합니다.


는 편집을 해결하기 위해 : type(i, j)에서 i가 0보다 다른 것을이

경우, 메모리 액세스가 여전히 스트라이드된다. 따라서 벡터화하기가 어려울 것입니다. (비록 효율성이 낮더라도 매우 작은 컴파일 타임 - 결정화 된 진보가 가능하기 때문에 "불가능"대신 "어렵다"라고 말합니다.)

여기서 핵심 문제는 행을 반복하는 것입니다 행렬의 수집/분산 지원없이 벡터화 할 수있을뿐만 아니라 캐시에도 좋지 않습니다.

어떤 작업을 수행 하려는지 확실하지 않지만 최대 성능을 얻으려면 다른 데이터 레이아웃을 고려해야 할 수도 있습니다.

+0

5:38 AM 여기. 나는 잠을 자야 해 ... – Mysticial

+0

+1 항상 훌륭한 분석. –

+0

다른 데이터 레이아웃 - MxN "매트릭스"대신 크기 (M * N)의 1 차원 배열을 사용하고 mod 및 div 연산을 사용하여 조작 할 수 있습니다. 기본적으로 더프의 장치에 대한 기초를 만듭니다 꽤 잘 최적화 된 – technosaurus