Como ver quais sinalizadores -march = native serão ativados?

165

Estou compilando meu aplicativo C ++ usando o GCC 4.3. Em vez de selecionar manualmente os sinalizadores de otimização que estou usando -march=native, o que, em teoria, deve adicionar todos os sinalizadores de otimização aplicáveis ​​ao hardware no qual estou compilando. Mas como posso verificar quais sinalizadores ele realmente está usando?

vartec
fonte

Respostas:

150

Você pode usar as -Q --help=targetopções:

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

A -vopção também pode ser útil.

Você pode ver a documentação na --helpopção aqui .

thkala
fonte
10
Vou sugerir que isso é subótimo. A saída de --help = target não exibe informações de cache da CPU, cujos métodos elias e 42n4 abaixo foram listados. Especificamente, no gcc 4.9.2 em um Phenom, a saída inclui os seguintes:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos
@DanielSantos: no meu sistema ele não exibir esses parâmetros com a -vopção, embora como parte da cc1linha de comando ...
thkala
imperfeito. na versão 5.4.0 do gcc (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty), causará o erro de retorno: Mensagens do Assembler: Erro: arquitetura desconhecida nativa Erro: opção não reconhecida -march = native. Então, solta o -march=nativee irá funcionar em todos os lugares apenas seguir: gcc -Q --help=target.
Oleg Kokorin
@Oleg - que soa como um bug no GCC 5. A questão não está presente no GCC 7.
JWW
111

Para ver sinalizadores de linha de comando, use:

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

Se você deseja ver as definições do compilador / pré-compilador definidas por determinados parâmetros, faça o seguinte:

echo | gcc -dM -E - -march=native
elias
fonte
1
Essa resposta merece tantos votos positivos quanto os aceitos por, em particular, listar o que nativerealmente significa.
Iwillnotexist Idonotexist
4
Então, se eu gostaria de compilar entre nativos, devo alimentar o compilador, tanto o define E os argumentos? ou os argumentos são suficientes?
precisa saber é o seguinte
25

Deve ser ( -###é semelhante a -v):

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

Para mostrar os sinalizadores nativos "reais" para o gcc.

Você pode fazê-los aparecer mais "claramente" com um comando:

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

e você pode se livrar de sinalizadores com -mno- * com:

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

Se você quiser descobrir como configurar uma compilação cruzada não nativa, achei útil:

Na máquina de destino,

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

Em seguida, use isso na máquina de construção:

% gcc -march=core-avx-i ...
Mark Lakata
fonte
Infelizmente, isso não inclui todas as bandeiras.
Baptiste Wicht
@BaptisteWicht existem sinalizadores que -march = native incluirão que -march = core-avx-i não, nesse caso, ou quais sinalizadores? Obrigado!
Rogerdpack
2
@rogerdpack Neste computador (sandybridge), march = sandybridge não habilita o AVX (não sei por que) enquanto march = native faz. Outra diferença importante é que os tamanhos de cache apenas são extraídos com marcha = nativa
Baptiste Wicht
1
@BaptisteWicht que estranho parece funcionar aqui (eu acho): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1mas os tamanhos de cache parecem ausentes.
Rogerdpack
7

Vou jogar meus dois centavos nessa questão e sugerir uma extensão um pouco mais detalhada da resposta de Elias. A partir do gcc 4.6, a execução de gcc -march=native -v -E - < /dev/nulluma quantidade crescente de spam na forma de -mno-*sinalizadores supérfluos . O seguinte removerá estes:

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

No entanto, verifiquei apenas a correção disso em duas CPUs diferentes (Intel Core2 e AMD Phenom), por isso sugiro executar o script a seguir para garantir que todos esses -mno-*sinalizadores possam ser removidos com segurança.

#!/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}.$$

Não encontrei diferença entre gcc -march=native -v -E - < /dev/nullegcc -march=native -### -E - < /dev/null além de alguns parâmetros serem citados - e parâmetros que não contêm caracteres especiais; portanto, não tenho certeza em que circunstâncias isso faz alguma diferença real.

Por fim, observe que --march=native foi introduzido no gcc 4.2, antes do qual é apenas um argumento não reconhecido.

Daniel Santos
fonte
Nice, este gleans tem os tamanhos de cache bem
rogerdpack
O gcc versão 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) retorna: Erro: arquitetura desconhecida `nativa '
Oleg Kokorin
Oleg: Qual arco você está usando? Pode ser que "nativo" seja suportado apenas em algumas arquiteturas.
Daniel Santos