Jak sprawdzić, które flagi -march = native zostaną aktywowane?

165

Kompiluję moją aplikację w C ++ przy użyciu GCC 4.3. Zamiast ręcznie wybierać flagi optymalizacji -march=native, których używam , które teoretycznie powinny dodać wszystkie flagi optymalizacji mające zastosowanie do sprzętu, na którym kompiluję. Ale jak mogę sprawdzić, których flag faktycznie używa?

vartec
źródło

Odpowiedzi:

150

Możesz skorzystać z -Q --help=targetopcji:

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

Ta -vopcja może być również przydatna.

Możesz zobaczyć dokumentację dotyczącą --helpopcji tutaj .

thkala
źródło
10
Mam zamiar zasugerować, że jest to nieoptymalne. Dane wyjściowe --help = target nie wyświetlają informacji o pamięci podręcznej procesora, które zostały wymienione poniżej w metodach elias i 42n4. W szczególności, na gcc 4.9.2 na Phenomie, dane wyjściowe obejmują:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos,
@DanielSantos: w moim systemie wyświetla te parametry z -vopcją, choć jako część cc1wiersza poleceń ...
thkala
nie idealny. w wersji 5.4.0 gcc (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) spowoduje to zwrócenie błędu: Komunikaty asemblera: Błąd: nieznana architektura natywna Błąd: nierozpoznana opcja -march = natywna. Więc luźne -march=nativei będzie działać wszędzie tylko następujące: gcc -Q --help=target.
Oleg Kokorin
@Oleg - To brzmi jak błąd w GCC 5. Problem nie występuje w GCC 7.
jww
111

Aby zobaczyć flagi wiersza poleceń, użyj:

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

Jeśli chcesz zobaczyć definicje kompilatora / prekompilatora ustawione przez określone parametry, zrób to:

echo | gcc -dM -E - -march=native
elias
źródło
1
Ta odpowiedź zasługuje na tyle samo głosów poparcia, ile zaakceptowano, w szczególności za wyszczególnienie tego, co nativenaprawdę oznacza.
Idonotexist Idonotexist
4
więc jeśli chciałbym skompilować cross-native-compile, powinienem podawać zarówno kompilatorowi zarówno definicje, jak i argumenty? czy też argumenty są wystarczające?
hanshenrik
25

Powinien być ( -###podobny do -v):

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

Aby pokazać "prawdziwe" flagi natywne dla gcc.

Możesz sprawić, by wyglądały bardziej „wyraźnie” za pomocą polecenia:

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

i możesz pozbyć się flag przez -mno- * za pomocą:

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

Jeśli chcesz dowiedzieć się, jak skonfigurować nienatywną kompilację krzyżową, uznałem to za przydatne:

Na maszynie docelowej

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

Następnie użyj tego na maszynie kompilacji:

% gcc -march=core-avx-i ...
Mark Lakata
źródło
Niestety nie obejmie to wszystkich flag.
Baptiste Wicht
@BaptisteWicht czy są flagi, których -march = native będzie zawierać, których -march = core-avx-i nie będzie w tym przypadku, lub które flagi? Dzięki!
rogerdpack
2
@rogerdpack Na tym komputerze (sandybridge), march = sandybridge nie włącza AVX (nie wiem dlaczego), podczas gdy march = native tak. Inną ważną różnicą jest to, że rozmiary pamięci podręcznej są wyodrębniane tylko za pomocą parametru march = native
Baptiste Wicht
1
@BaptisteWicht to dziwne wydaje się działać tu (chyba): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1ale rozmiary cache wydaje nieobecny.
rogerdpack
7

Zamierzam wrzucić moje dwa centy w to pytanie i zasugerować nieco bardziej rozwlekłe rozszerzenie odpowiedzi Eliasza. Począwszy od gcc 4.6, uruchamianie programu gcc -march=native -v -E - < /dev/nullemituje coraz większą ilość spamu w postaci zbędnych -mno-*flag. Następujące elementy usuwają te:

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

Jednak zweryfikowałem poprawność tego tylko na dwóch różnych procesorach (Intel Core2 i AMD Phenom), więc sugeruję również uruchomienie następującego skryptu, aby upewnić się, że wszystkie te -mno-*flagi można bezpiecznie usunąć.

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

Nie znalazłem różnicy między gcc -march=native -v -E - < /dev/nulli gcc -march=native -### -E - < /dev/nullinnymi niż niektóre cytowane parametry - i parametry, które nie zawierają znaków specjalnych, więc nie jestem pewien, w jakich okolicznościach ma to jakiekolwiek znaczenie.

Na koniec zwróć uwagę, że --march=nativezostał wprowadzony w gcc 4.2, przed którym jest to tylko nierozpoznany argument.

Daniel Santos
źródło
Fajnie, ten Gleans ma również rozmiary pamięci podręcznej
rogerdpack
gcc w wersji 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) zwraca: Błąd: nieznana architektura `` natywna ''
Oleg Kokorin
Oleg: Jakiego łuku używasz? Może się zdarzyć, że „natywny” jest obsługiwany tylko na niektórych architekturach.
Daniel Santos,