2013-06-26 9 views
1

많은 SIMD 내장 코드가있는 코드베이스에서 작업하고 있습니다. 이제 AVX2가 생겼으므로 비 AVX 가능 프로세서에서 실행되는 SIMD 코드가 있어야합니다.이 코드는 훨씬 더 많은 작업이 필요합니다. 게다가 AVX2 셔플에 대한 128 비트 레인 교차 제한은 상황을 복잡하게 만듭니다. 이러한 이유로 자동 벡터 라이 제이션에 더 많이 의존해야 할 때입니다. 나를 놀라게하는 주요 사항은 병렬성을 없애고 자동 벡터화 된 코드를 디버깅 할 수있는 가능성에 대한 문제입니다.자동 벡터화 된 루프를 디버깅 할 수 있습니까?

나는 g ++ -O1 -g -ftree - 벡터 라이와 다음 컴파일 및 GDB와 단계별 시도했습니다 (-ftree-벡터화 -O0 작동하지 않는 이유를 아는 사람입니까?)

float a[1000], b[1000], c[1000]; 
int main(int argc, char **argv) 
{ 
    for (int i = 0; i < argc; ++i) 
    c[i] = a[i] + b[i]; 
    return 0; 
} 

하지만 의미있는 결과는 얻지 못합니다. 예를 들어, 때로는 i 값이 <이라고 말하면서 >을 최적화하고 다른 시간은 20으로 점프합니다.

디버깅을 위해 SIMD 상태를 원래의 C 상태로 매핑하는 것이 어렵다는 것이 주요 문제인 것 같습니다. 하지만 현실적으로 할 수 있습니까?

+0

왜 디버깅 하시겠습니까? 벡터화되었는지 확인하려면 어셈블리 코드를 검사하거나 벤치 마크를 실행하는 것이 더 낫지 않습니까 (전체 최적화 설정에서)? 버그를 찾으려면 비 벡터 라이 제이션 (및 최적화되지 않은) 버전을 디버깅하십시오. – delnan

+0

예, 컴파일러 버그가 발생하는 경우와 때 그들은 심술 궂은 경우. 나는 (소스 레벨) 디버거가 올바른 접근 방법인지는 모르지만 어쨌든 이해한다. – delnan

+0

오류에 대한 디버깅은 대부분 가설입니다.Visual C++ 2010 벡터 라이저에서 정렬되지 않은로드를 산술 명령어로 부적절하게 단일 x86 명령어로 통합하여 정렬되지 않은 배열에서 실행할 때 충돌이 발생하는 버그를 제출 한 것을 기억합니다. –

답변

0

자동 벡터화 된 코드에서 디버거를 사용하는 것은 까다 롭습니다. 루프 카운터와 같이 다르게 동작해야하는 변수를 검사하려는 경우

디버그 빌드 (-O0 또는 -Og)를 사용하거나 컴파일러가 코드를 벡터화 한 방법을 이해하고 레지스터 asm 및 레지스터를 검사 할 수 있습니다. 추적해야 할 버그 종류에 따라 자동 벡터화 된 빌드에 문제가 있거나 없을 수도 있습니다.

코드에서 로직 버그를 수정하기 위해 실제로 디버깅하는 것이 아니라 자동 벡터화의 효율성을 확인하는 데 더 많은 관심이있는 것처럼 들립니다. ASM과 벤치 마크를 살펴보면 아마도 가장 좋은 방법 일 것입니다. (심지어 전화 전후에 단순한 심지어 rdtsc) 또는 정확성뿐만 아니라 성능을 테스트하는 단위 테스트에서 사용됩니다.

때때로 컴파일러는 여러 버전의 루프를 생성합니다. 입력 배열이 겹치는 경우와 배열이 겹치지 않는 경우입니다. 실제로 대부분의 작업을 수행하는 루프를 찾을 때까지 단일 단계 (지침에 따라 stepi, layout asm)를 사용하면 도움이됩니다. 그런 다음 벡터화 된 방식에 중점을 둘 수 있습니다. 수표와 다른 버전을 제거하려면 restrict 포인터가 도움이 될 수 있습니다. p = __builtin_assume_aligned(p, 16)도 있습니다.

또한 Intel's free code analyzer을 사용하여 반복 수행 횟수를 정적으로 분석 할 수 있습니다. 루프 몸체의 맨 위에 IACA 표시를하고 루프의 닫는 괄호 뒤에 GCC가 자동 벡터화 된 루프의 적절한 위치에 표시하고 인라인 asm이 자동 벡터화를 중단하지 않기를 바랍니다.

http://agner.org/optimize/에 대한 링크가 포함 된 최적화 대답이 없으므로 여기로 이동하십시오.