2013-04-18 2 views
3

저는 VC++ 2012에서 이와 같은 비트를 보이는 루프를 자동 벡터 라이즈하려고합니다 (실제로 흥미로운 계산이 있지만 가능한 한 포인트를 질문 할 목적으로 생략했습니다). Visual C++에서이 루프를 벡터화하는 방법 (오류 코드 1200)?

parameters: 
int period; 
unsigned char* out_array; 
unsigned char* in_array1; 
unsigned char* in_array2; 
unsigned char* in_array3; 

for (int x = 0; x < width; ++x) 
{ 
    int index = period * (x/2); 

    out_array[0] = in_array1[x]; 
    out_array[1] = in_array2[index]; 
    out_array[2] = in_array3[index]; 
    out_array += 4; 
} 

나는 벡터화의 길에 서있는 유일한 것은 out_array += 4라고 생각, 그래서 나는 적어도 하나는 벡터화 할 수있는 희망, 내부 "풀려"루프를 만들어 :

for (int x = 0; x < width; ++x) 
{ 
    for (int xx = 0; xx < 4; ++xx) 
    { 
     int index = period * ((xx + x)/2); 

     unsigned char* pout_array = out_array + (4 * xx); 
     pout_array[0] = in_array1[xx + x]; 
     pout_array[1] = in_array2[index]; 
     pout_array[2] = in_array3[index]; 
    } 
    out_array += 16; 
} 

그러나로를 I

루프에 의존적 루프 수행 데이터를 포함 /Qvect-report:2와 컴파일러를 실행, 그것은 나에게 내부 루프를 말하고 이유로 인해 오류 코드 1200 오류 코드 1200 주 벡터화 할 수 없습니다 den35는 벡터화를 방지합니다. 루프의 반복이 각각 기타와 간섭하여 루프를 벡터화하면 잘못된 대답이 발생하고 자동 벡터 라이저는 그러한 데이터가 없음을 자체적으로 증명할 수 없습니다.

나는 이것을 이해하지 못한다. 분명히이 루프의 각 반복은 독립적입니다. Visual Studio에서 벡터화하려면 어떻게해야합니까?

+1

컴파일러는 4 개의 배열이 겹치거나 별칭이 아닌 것을 증명할 수 없습니다. 그건 제외하고,이 루프가 처음부터 쉽게 벡터화 할 수 있는지 확실하지 않습니다. 나는 너무 익숙하지 않아서 intrinsics를 통해이 순진한 접근 방식보다 더 잘 할 수있다. – Mysticial

+0

2 개의 루프로 나누고, 1은 out_array [0] = in_array1 [x]; 하나는 다른 2와 결합합니다. 그러면 컴파일러는 어떤 루프를 사용하여 불평합니까? –

+0

@Mystical 3 루프로 분할하여 해결할 수 있습니다. –

답변

2

이렇게 벡터화 할 수없는 주된 이유는 컴파일러가 out_array [n]이 in_arrayX [m]이 아닌 가능성을 제거 할 수 없으므로 순차적 순서 지정을 준수해야한다는 것입니다.

"__restrict"또는 "restrict"키워드를 사용하여 컴파일러에서이 문제를 해결할 수 있습니다.이 키워드는 out_array가 다른 세 가지 변수와 동일하지 않도록 컴파일러에게 약속합니다. 포인터. 컴파일러를 돕기 위해 "const"수정자를 많이 사용하고자 할 수도 있습니다.

void func(const int period, 
    unsigned char* __restrict out_array, 
    const unsigned char* in_array1, 
    const unsigned char* in_array2, 
    const unsigned char* in_array3) 
{ 
    ... 
    //mark 'width' as 'const' if possible: 
    const int width = ...; 
    for (int x = 0; x < width; ++x) 
    { 
     const int index = period * (x/2); 

     out_array[(x* 4) + 0] = in_array1[x]; 
     out_array[(x* 4) + 1] = in_array2[index]; 
     out_array[(x* 4) + 2] = in_array3[index]; 
    } 
}