문제

GCC로 자동 벡터화 작업을하고 있습니다. 고객 요구 사항으로 인해 고유 나 속성을 사용할 수있는 위치에 있지 않습니다. (벡터화를 지원하기 위해 사용자 입력을 얻을 수 없습니다)

벡터화 할 수있는 배열의 정렬 정보가 알려지지 않은 경우 GCC는 '루프 버전화'에 대한 패스를 호출합니다. 루프 벡터화가 나무에서 완료되면 루프 버전화가 수행됩니다. 루프가 벡터화 가능한 것으로 식별되고 데이터 정렬 또는 데이터 의존성에 대한 제약이 방해하는 경우 (컴파일 시간에 결정할 수 없기 때문에) 두 가지 버전의 루프가 생성됩니다. 이들은 루프의 벡터 및 비 벡터 버전과 함께 런타임 검사와 정렬 또는 의존성을위한 런타임 검사입니다.

내 질문은 우리가 어떻게 정렬을 시행해야합니까? 벡터화 가능한 루프를 찾은 경우 정렬 정보가 누락되어 두 가지 버전의 루프를 생성해서는 안됩니다.

예를 들어. 아래 코드를 고려하십시오

short a[15]; short b[15]; short c[15];
int i;

void foo()
{
    for (i=0; i<15; i++)
    {
      a[i] = b[i] ;
    }
}

트리 덤프 (옵션 : -fdump-tree-op-pottinized -ftree-vectorize)

<SNIP>
     vector short int * vect_pa.49;
     vector short int * vect_pb.42;
     vector short int * vect_pa.35;
     vector short int * vect_pb.30;

    bb 2>:
     vect_pb.30 = (vector short int *) &b;
     vect_pa.35 = (vector short int *) &a;
     if (((signed char) vect_pa.35 | (signed char) vect_pb.30) & 3 == 0)    ;; <== (A)
       goto <bb 3>;
     else
       goto <bb 4>;

    bb 3>:
</SNIP>

벡터화 된 코드의 'BB 3'버전이 생성됩니다. 벡터화가없는 'BB 4'코드가 생성됩니다. 이들은 정렬을 확인하여 수행됩니다 ( 'a'). 이제 고유 및 기타 속성을 사용하지 않고 벡터화 된 코드 만 어떻게 얻어야합니까 (이 런타임 정렬 점검없이).

도움이 되었습니까?

해결책

해당 데이터가 정적으로 할당되면 __align__ GCC가 지원하는 것이 필요한 경계에 정렬되어야한다고 지정합니다. 이 배열을 동적으로 할당하는 경우 정렬 값으로 과도 할 수있는 다음 반환 된 포인터를 필요한 정렬까지 부딪 칠 수 있습니다.

당신은 또한 사용할 수 있습니다 posix_memalign() 기능을 지원하는 시스템에있는 경우 기능. 마지막으로, 그 점에 유의하십시오 malloc() 항상 가장 큰 내장 유형의 크기, 일반적으로 이중으로 8 바이트의 크기에 맞게 메모리를 할당합니다. 그보다 더 나은 것이 필요하지 않다면 malloc 충분해야합니다.

편집하다: 할당 코드를 수정하여 해당 수표를 강제로 수정하면 (즉, 위에서 제안한대로 전체적으로) 컴파일러는 루프 코드를 조건부화하지 않아야합니다. 8 바이트 경계에 정렬해야한다면 a = (a + 7) & ~3;.

다른 팁

루프의 버전 만 얻습니다. 이 옵션과 함께 정확한 코드 사용 : gcc -march=core2 -c -O2 -fdump-tree-optimized -ftree-vectorize vec.c

내 버전의 GCC입니다 gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8).

GCC는 여기서 영리한 일을하고 있습니다. 배열을 강요합니다 a 그리고 b 16 바이트 정렬됩니다. 그렇게하지 않습니다 c, 아마도 그 때문일 것입니다 c 벡터화 가능한 루프에는 사용되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top