c gcc optimization performance-testing compiler-optimization

Deshabilite todas las opciones de optimización en GCC



optimization performance-testing (3)

Bien

gcc -O0 `gcc -Q -O0 --help=optimizers 2>&1 | perl -ane ''if ($F[1] =~/enabled/) {$F[0] =~ s/^/s*-f/-fno-/g;push @o,$F[0];}} END {print join(" ", @o)''` your args here

desactivará todas las opciones (qué asco).

Más en serio, si está cubriendo todos los estados de optimización, haga una lista de los indicadores de optimización (que debe hacer de todos modos) y active o desactive explícitamente cada uno con -fmyflag o -fno-myflag . En esencia, esto responde a su segunda pregunta.

Sin embargo, puede considerar que no vale la pena jugar apagando las optimizaciones que están activadas para todos los niveles de -O .

En cuanto a por qué es así, eso está en algún lugar entre ''demasiado amplio'' (es decir, tendría que preguntarle a quien lo escribió) y ''porque eso es lo que https://github.com/gcc-mirror/gcc/blob/master/gcc/toplev.c hace '' .

Tenga en cuenta que la documentación no dice que -O0 deshabilita la optimización. Dice (de la página del manual ):

-O0 Reduzca el tiempo de compilación y haga que la depuración produzca los resultados esperados. Este es el valor predeterminado.

Por implicación, puede haber optimizaciones que no aumenten el tiempo de compilación y no afecten la depuración, y se dejarán activadas.

El nivel de optimización predeterminado para compilar programas C usando GCC es -O0. que desactiva todas las optimizaciones de acuerdo con la documentación de GCC. por ejemplo:

gcc -O0 test.c

Sin embargo, para verificar si -O0 realmente está desactivando todas las optimizaciones . Ejecuté este comando:

gcc -Q -O0 --help=optimizers

Y aquí, estaba un poco sorprendido. Tengo alrededor de 50 opciones habilitadas. Luego, verifiqué los argumentos predeterminados pasados ​​a gcc usando esto:

gcc -v

Tengo esto:

Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion=''Ubuntu 4.8.4- 2ubuntu1~14.04'' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs -- enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr -- program-suffix=-4.8 --enable-shared --enable-linker-build-id -- libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with- gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with- sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx- time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin -- with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk- cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable- java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with- jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch- directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc- gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 -- with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)

Entonces, mi conclusión es que el indicador -O0 que proporcioné al programa no fue anulado por otra cosa.

De hecho, estoy buscando implementar desde cero una herramienta que genere secuencias aleatorias de opciones de optimización y compare las secuencias generadas con los niveles predeterminados 0-3. Al igual que "acovea". Entonces, me gustaría comparar mis secuencias generadas con un nivel de optimización cero (que debería ser -O0 )

¿Me puede explicar por qué 50 opciones están habilitadas por defecto en -O0 ?

Una idea que tengo en mente es compilar con -O0 y desactivar las optimizaciones predeterminadas en -O0 usando -fno-OPTIMIZATION_NAME 50 veces. ¿Qué piensas?


Para responder a mi pregunta, he hecho algunas conclusiones y suposiciones:

Permítanme decir que compilar con O0 no significa que no se aplicarán optimizaciones. Las opciones que reducen el tiempo de compilación y mejoran la depuración se activarán como @abligh dijo anteriormente.

En otras palabras, O0 se está optimizando en el nivel de compilación. Los binarios producidos no están optimizados para facilitar el proceso de depuración.

Doy un ejemplo: esta opción está habilitada en el nivel O0

optimizaciones de bucle agresivo

En la documentación de GCC:

Esta opción le dice al optimizador de bucles que use restricciones de lenguaje para derivar límites para la cantidad de iteraciones de un bucle. Esto supone que el código de bucle no invoca un comportamiento indefinido, por ejemplo, causando desbordamientos de enteros firmados o accesos de matriz fuera del límite. Los límites para el número de iteraciones de un bucle se usan para guiar las optimizaciones de desenrollado y pelado del bucle y la prueba de salida del bucle. Esta opción está activada de forma predeterminada.

Entonces, para GCC 4.8.x, hay casi 50 opciones activadas de manera predeterminada.


Stricto sensu, el compilador GCC de gama media está hecho de una secuencia (en realidad un árbol anidado, que cambia dinámicamente durante la compilación) de pases de optimización, por lo que si GCC no realizó la optimización, no podrá emitir ningún código.

Piénselo de otra manera: el lenguaje de entrada a GCC es bastante rico (incluso para C simple, donde tiene while , for , ...) pero el lenguaje Gimple intermedio es mucho más pobre (en particular Gimple / SSA), por lo que necesita aplicar algunas transformaciones para pasar de la fuente AST a Gimple. Estas transformaciones son pases de optimización, casi por definición.

Vea también las imágenes de esa answer y this (una imagen SVG) y lea las referencias mencionadas here .

Debe entender que -O0 deshabilita las optimizaciones adicionales (por ejemplo, proporcionadas por -O1 etc.) no necesarias para producir algún ejecutable.