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

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


조회수 257


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를 줄 수 있습니다.


로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close