Come vedere quali flag -march = native si attiverà?


165

Sto compilando la mia app C ++ usando GCC 4.3. Invece di selezionare manualmente i flag di ottimizzazione che sto usando -march=native, che in teoria dovrebbe aggiungere tutti i flag di ottimizzazione applicabili all'hardware su cui sto compilando. Ma come posso verificare quali flag sta effettivamente utilizzando?

Risposte:


150

Puoi usare le -Q --help=targetopzioni:

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

L' -vopzione può anche essere utile.

Puoi vedere la documentazione --helpsull'opzione qui .


10
Sto per suggerire che questo non è ottimale. L'output di --help = target non visualizza le informazioni sulla cache della CPU, di cui sono elencati i metodi sia elias che 42n4 di seguito. In particolare, su gcc 4.9.2 su un Phenom, l'output include questi:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos,

@DanielSantos: sul mio sistema visualizza quei parametri con l' -vopzione, anche se come parte della cc1riga di comando ...
thkala

non perfetto. su gcc versione 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) causerà l'errore in cambio: Messaggi assemblatore: Errore: architettura sconosciuta nativa Errore: opzione non riconosciuta -march = native. Così, perdere la -march=nativee funzionerà ovunque solo seguendo: gcc -Q --help=target.
Oleg Kokorin,

@Oleg - Sembra un bug in GCC 5. Il problema non è presente in GCC 7.
jww

111

Per visualizzare i flag della riga di comando, utilizzare:

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

Se vuoi vedere il compilatore / precompilatore definito da determinati parametri, fai come segue:

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

1
Questa risposta merita tanti voti quanti quelli accettati per, in particolare, elencare ciò nativeche equivale veramente.
Iwillnotexist Idonotexist

4
quindi se vorrei compilare in modo nativo, dovrei alimentare sia il compilatore sia le definizioni E gli argomenti? o gli argomenti sono sufficienti?
Hanshenrik,

25

Dovrebbe essere ( -###è simile a -v):

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

Per mostrare i "veri" flag nativi per gcc.

Puoi farli apparire più "chiaramente" con un comando:

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

e puoi sbarazzarti delle bandiere con -mno- * con:

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

10

Se vuoi scoprire come impostare una compilazione incrociata non nativa, ho trovato questo utile:

Sulla macchina target,

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

Quindi utilizzare questo sulla macchina di compilazione:

% gcc -march=core-avx-i ...

Questo non includerà purtroppo tutte le bandiere.
Baptiste Wicht,

@BaptisteWicht ci sono flag che -march = native includerà che -march = core-avx-i non, in questo caso, o quali flag? Grazie!
rogerdpack,

2
@rogerdpack Su questo computer (sandybridge), march = sandybridge non abilita AVX (non so perché) mentre march = native lo fa. Un'altra differenza importante è che le dimensioni della cache vengono estratte solo con march = native
Baptiste Wicht il

1
@BaptisteWicht sembra strano che funzioni qui (immagino): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1ma le dimensioni della cache sembrano assenti.
rogerdpack,

7

Lancerò i miei due centesimi in questa domanda e suggerirò un'estensione leggermente più dettagliata della risposta di elias. A partire da gcc 4.6, l'esecuzione di gcc -march=native -v -E - < /dev/nullemette una quantità crescente di spamming sotto forma di -mno-*flag superflui . Quanto segue eliminerà questi:

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

Tuttavia, ho verificato la correttezza di ciò solo su due diverse CPU (un Intel Core2 e AMD Phenom), quindi suggerisco di eseguire anche il seguente script per essere sicuro che tutti questi -mno-*flag possano essere rimossi in modo sicuro.

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

Non ho trovato alcuna differenza tra i parametri citati gcc -march=native -v -E - < /dev/nulle gcc -march=native -### -E - < /dev/nulldiversi da quelli citati - e i parametri che non contengono caratteri speciali, quindi non sono sicuro in quali circostanze ciò faccia davvero la differenza.

Infine, nota che è --march=nativestato introdotto in gcc 4.2, prima del quale è solo un argomento non riconosciuto.


Bello, questo ha anche le dimensioni della cache
rogerdpack

gcc versione 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) restituisce: Errore: architettura sconosciuta `native '
Oleg Kokorin

Oleg: quale arco stai usando? È possibile che "nativo" sia supportato solo su alcune architetture.
Daniel Santos,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.