GCC가 a*a*a*a*a*a를 (a*a*a)*(a*a*a)로 최적화하질 않습니다.

발생하는 문제 및 실행환경

컴파일러가 pow(a,2)a*a로 최적화하는 걸로 알고 있는데 pow(a,6)는 최적화하지 않고 라이브러리 함수 pow()를 부릅니다.

C++ 인텔 컴파일러는 6까지 최적화해주는데 왜 GCC C컴파일러는 2는 최적화하면서 6은 최적화하지 않나요?

궁금해서 GCC 4.5.1에 "-O3 -lm -funroll-loops -msse4" 옵션으로 pow(a,6) 자리에 a*a*a*a*a*a를 넣어 봤을 때는 이렇게

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13

나온 반면에 (a*a*a)*(a*a*a)를 쓰니까 훨씬 더 빨리 실행됐습니다.

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13

컴파일러가 왜 최적화를 안하죠?

1답변

  • 좋아요

    0

    싫어요
    채택취소하기

    부동소수점 연산은 컴퓨터 수학의 관점에서는 결합 법칙이 성립하지 않습니다.

    그래서 a*a*a*a*a*a(a*a*a)*(a*a*a)가 다른 결과를 낼 수 있기 때문에 컴파일러가 최적화를 하지 않습니다.

    제 컴퓨에서 실험해봐도

    int main(){
        float a = 3.9989391;
        printf("%f\n", a*a*a*a*a*a);
        printf("%f\n", (a*a*a)*(a*a*a));
    }
    

    출력 :

    4089.485840
    4089.485596
    

    둘이 다른 결과를 냅니다.

    속도를 빨리하기 위해서 약간의 오차를 허용한다면 컴파일러에 옵션 -fassociative-math이나 -ffast-math를 줄 수 있습니다.

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.