Why doesn't GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)?

前端 未结 12 1568
孤街浪徒
孤街浪徒 2020-11-22 08:41

I am doing some numerical optimization on a scientific application. One thing I noticed is that GCC will optimize the call pow(a,2) by compiling it into a

12条回答
  •  死守一世寂寞
    2020-11-22 09:42

    GCC does actually optimize a*a*a*a*a*a to (a*a*a)*(a*a*a) when a is an integer. I tried with this command:

    $ echo 'int f(int x) { return x*x*x*x*x*x; }' | gcc -o - -O2 -S -masm=intel -x c -
    

    There are a lot of gcc flags but nothing fancy. They mean: Read from stdin; use O2 optimization level; output assembly language listing instead of a binary; the listing should use Intel assembly language syntax; the input is in C language (usually language is inferred from input file extension, but there is no file extension when reading from stdin); and write to stdout.

    Here's the important part of the output. I've annotated it with some comments indicating what's going on in the assembly language:

    ; x is in edi to begin with.  eax will be used as a temporary register.
    mov  eax, edi  ; temp = x
    imul eax, edi  ; temp = x * temp
    imul eax, edi  ; temp = x * temp
    imul eax, eax  ; temp = temp * temp
    

    I'm using system GCC on Linux Mint 16 Petra, an Ubuntu derivative. Here's the gcc version:

    $ gcc --version
    gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
    

    As other posters have noted, this option is not possible in floating point, because floating point arithmetic is not associative.

提交回复
热议问题