¿Cómo ver qué banderas se activarán -march = native?

165

Estoy compilando mi aplicación C ++ usando GCC 4.3. En lugar de seleccionar manualmente los indicadores de optimización que estoy usando -march=native, que en teoría debería agregar todos los indicadores de optimización aplicables al hardware en el que estoy compilando. Pero, ¿cómo puedo verificar qué banderas está usando realmente?

vartec
fuente

Respuestas:

150

Puedes usar las -Q --help=targetopciones:

gcc -march=native -Q --help=target ...

La -vopción también puede ser de utilidad.

Puede ver la documentación sobre la --helpopción aquí .

thkala
fuente
10
Voy a sugerir que esto es subóptimo. La salida de --help = target no muestra la información de la memoria caché de la CPU, de la cual se han enumerado los métodos elias y 42n4 a continuación. Específicamente, en gcc 4.9.2 en un Phenom, la salida incluye estos:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos
@DanielSantos: en mi sistema muestra esos parámetros con la -vopción, aunque como parte de la cc1línea de comando ...
thkala
no es perfecto. en gcc versión 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) causará el error a cambio: Mensajes del ensamblador: Error: arquitectura desconocida nativa Error: opción no reconocida -march = native. Por lo tanto, perder el -march=nativey funcionará en todas partes simplemente siguiente: gcc -Q --help=target.
Oleg Kokorin
@Oleg - Eso suena como un error en GCC 5. El problema no está presente en GCC 7.
jww
111

Para ver banderas de línea de comandos, use:

gcc -march=native -E -v - </dev/null 2>&1 | grep cc1

Si desea ver las definiciones del compilador / precompilador establecidas por ciertos parámetros, haga lo siguiente:

echo | gcc -dM -E - -march=native
elias
fuente
1
Esta respuesta merece tantos votos positivos como la aceptada para, en particular, enumerar lo que nativerealmente equivale.
Iwillnotexist Idonotexist
44
Entonces, si me gustaría compilar de forma cruzada, ¿debo alimentar tanto el compilador como las definiciones Y los argumentos? o son suficientes los argumentos?
hanshenrik
25

Debería ser ( -###es similar a -v):

echo | gcc -### -E - -march=native 

Para mostrar las banderas nativas "reales" para gcc.

Puede hacer que aparezcan más "claramente" con un comando:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )//g'

y puedes deshacerte de las banderas con -mno- * con:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )|( -mno-[^\ ]+)//g'
42n4
fuente
10

Si desea averiguar cómo configurar una compilación cruzada no nativa, esto me pareció útil:

En la máquina de destino,

% gcc -march=native -Q --help=target | grep march
-march=                               core-avx-i

Luego use esto en la máquina de compilación:

% gcc -march=core-avx-i ...
Mark Lakata
fuente
Esto no incluirá todas las banderas desafortunadamente.
Baptiste Wicht
@BaptisteWicht ¿hay indicadores que -march = native incluirán que -march = core-avx-i no, en este caso, o qué indicadores? ¡Gracias!
rogerdpack
2
@rogerdpack En esta computadora (sandybridge), march = sandybridge no habilita AVX (no sé por qué) mientras que march = native sí. Otra diferencia importante es que los tamaños de caché solo se extraen con march = native
Baptiste Wicht
1
@BaptisteWicht que parece extraño funciona aquí (supongo): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1pero los tamaños de caché parecen ausentes.
rogerdpack
7

Voy a poner mis dos centavos en esta pregunta y sugerir una extensión un poco más detallada de la respuesta de elias. A partir de gcc 4.6, la ejecución de gcc -march=native -v -E - < /dev/nullemite una cantidad cada vez mayor de correo no deseado en forma de -mno-*indicadores superfluos . Lo siguiente los quitará:

gcc -march=native -v -E - < /dev/null 2>&1 | grep cc1 | perl -pe 's/ -mno-\S+//g; s/^.* - //g;'

Sin embargo, solo he verificado la corrección de esto en dos CPU diferentes (un Intel Core2 y AMD Phenom), por lo que sugiero también ejecutar el siguiente script para asegurarme de que todos estos -mno-*indicadores se puedan quitar de forma segura.

#!/bin/bash

gcc_cmd="gcc"

# Optionally supply path to gcc as first argument
if (($#)); then
    gcc_cmd="$1"
fi

with_mno=$(
    "${gcc_cmd}" -march=native -mtune=native -v -E - < /dev/null 2>&1 |
    grep cc1 |
    perl -pe 's/^.* - //g;'
)
without_mno=$(echo "${with_mno}" | perl -pe 's/ -mno-\S+//g;')

"${gcc_cmd}" ${with_mno}    -dM -E - < /dev/null > /tmp/gcctest.a.$$
"${gcc_cmd}" ${without_mno} -dM -E - < /dev/null > /tmp/gcctest.b.$$

if diff -u /tmp/gcctest.{a,b}.$$; then
    echo "Safe to strip -mno-* options."
else
    echo
    echo "WARNING! Some -mno-* options are needed!"
    exit 1
fi

rm /tmp/gcctest.{a,b}.$$

No he encontrado una diferencia entre gcc -march=native -v -E - < /dev/nully gcc -march=native -### -E - < /dev/nullaparte de algunos parámetros que se citan, y parámetros que no contienen caracteres especiales, por lo que no estoy seguro de en qué circunstancias esto hace una diferencia real.

Finalmente, tenga en cuenta que --march=nativese introdujo en gcc 4.2, antes de lo cual es solo un argumento no reconocido.

Daniel Santos
fuente
Bien, este gleans también tiene los tamaños de caché
rogerdpack
gcc versión 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) devuelve: Error: arquitectura desconocida 'nativa'
Oleg Kokorin
Oleg: ¿Qué arco estás usando? Podría ser que "nativo" solo sea compatible con algunas arquitecturas.
Daniel Santos