2012-03-26 3 views
1

임베디드 아키텍처에서 for 루프를 최적화하기 위해이 옵션을 사용했습니다 (here). 그러나 정렬에서 하나 이상의 nop 명령어를 추가해야하는 경우 컴파일러에서 nop을 하나씩 생성하고 as-many-as-required 0 (0000)을 생성합니다.-falign-loops 옵션을 사용할 때 GCC 버그입니까?

우리 컴파일러의 버그라고 생각되지만 누군가 GCC의 버그가 아닌지 확인할 수 있습니까? -falign-loops=8 (또는 필요한 최소 정렬보다 더 아키텍처와 관련된 어떤 번호)와

__asm__ volatile("nop"); 
    __asm__ volatile("nop"); 

    for (j0=0; j0<N; j0+=4) 
    { 
     c[j0+ 0] = a[j0+ 0] + b[j0+ 0]; 
     c[j0+ 1] = a[j0+ 1] + b[j0+ 1]; 
     c[j0+ 2] = a[j0+ 2] + b[j0+ 2]; 
     c[j0+ 3] = a[j0+ 3] + b[j0+ 3]; 
    } 

컴파일 :

는 여기에 코드입니다. 필요에 따라 __asm__ 행을 추가하거나 제거하여 잘못 정렬 된 루프 본문을 생성 할 수 있습니다.

+0

덧붙여서, 나는 추악한 수동 루프 풀기를 없애고 gcc가 루프를 풀도록 할 것입니다. (루프가 풀리면, 그것이 의미가 있다고 생각할 때'-O3'으로 디폴트로 할 것입니다). –

+0

@R .. - 분명히 현실 세계에서는 그렇지 않습니다. 이 코드는 사실 벡터 추가 작업을 수행하는 벤치 마크의 일부입니다. 나는 위의 코드와 vecadd()와 vecadd_naive()의 두 가지 함수를 제안과 비슷하게 사용한다. 사실, 최적의 성능을 얻으려면 수동으로 16 번 풀어야했고, 순진한 버전보다 약간 나은 성능을 보였습니다. 이것은 -O3 및 (아마도 중복) -funroll-loops와 함께 사용되었습니다. – ysap

+0

@R ..- 언 롤링 루프에 대한 옵티 마이저의 휴리스틱 스는 다소 임의의 규칙 집합 (OK, 사용 가능한 옵션이 적어도 있음)을 기반으로한다는 것을 기억하십시오. 코드 크기 또는 레지스터 사용과 같은 고려 사항은 다를 수 있으며 결국 더 빠른 코드로 이어질 수 있습니다. 나는 이것이 내가 차이점을 보았던 것이라고 생각한다. – ysap

답변

2

gcc -S -o foo.s foo.c을 사용하면 어셈블리 출력을 어셈블하지 않고 생성 할 수 있습니다. asm에 .balign 또는 .p2align 지시문이 표시됩니다. 이 지시어가 작동한다고 가정하면 어셈블러의 버그라고 생각합니다. 의도하지 않거나 실수로 (예 : .text이 아닌) 기본값이 아닌 섹션에 코드를 삽입 한 것일 수도 있습니다 (예 : 일부 다른 인라인 asm에서 .data 또는 .section). 일반적으로 어셈블러는 코드를 포함하는 섹션에 대해 적절한 크기와 수의 nop 명령어를 사용하고 데이터가 포함 된 섹션에는 0 바이트를 사용합니다.

+0

실제로 컴파일러는 올바른 위치에'.balign 8' 지시자를 삽입했습니다. 불행히도, 명시 적으로 채우기 값을 지정하지 않으면 어셈블러가 잘못된 시퀀스를 생성한다는 것을 이미 알게되었습니다. 내가 알 수있는 한, 함수는'.text' 섹션에 할당되어 있습니다. 컴파일러에게'-falign-loops = n'을 사용할 때 필러 값을 사용하도록 지시하는 방법이 있는지 궁금합니다. 예를 들어'.balignw 8,0x01a2'를 사용할 때처럼? – ysap

+0

어쨌든, 이것이 우리의 구현에 특별한가요? 아니면 GAS의 버그입니까? – ysap

+0

gcc 소스를 편집하여 플랫폼의 정렬을 위해 출력 어셈블리에 삽입하는 문자열을 변경하는 것이 가능합니다. 또는 GAS를 변경할 수 있습니다. 관리자가 문제가 있음을 확인할 수있는 경우 업스트림을 수락 할 수 있습니다. –

관련 문제