Wie kann man sehen, welche Flags -march = native aktiviert werden?

165

Ich kompiliere meine C ++ - App mit GCC 4.3. Anstatt die von mir verwendeten Optimierungsflags manuell auszuwählen -march=native, sollten theoretisch alle Optimierungsflags hinzugefügt werden , die für die Hardware gelten, auf der ich kompiliere. Aber wie kann ich überprüfen, welche Flags tatsächlich verwendet werden?

vartec
quelle

Antworten:

150

Sie können die folgenden -Q --help=targetOptionen verwenden:

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

Die -vOption kann auch von Nutzen sein.

Die Dokumentation zur --helpOption finden Sie hier .

thkala
quelle
10
Ich werde vorschlagen, dass dies nicht optimal ist. Die Ausgabe von --help = target zeigt keine CPU-Cache-Informationen an, von denen die Methoden elias und 42n4 unten aufgeführt sind. Insbesondere auf gcc 4.9.2 auf einem Phenom enthält die Ausgabe Folgendes:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos
@ DanielSantos: Auf meinem System werden diese Parameter mit der -vOption angezeigt , wenn auch als Teil der cc1Befehlszeile ...
thkala
nicht perfekt. In gcc Version 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-schmutzig) wird der Fehler zurückgegeben: Assembler-Meldungen: Fehler: unbekannte Architektur native Fehler: Nicht erkannte Option -march = native. Also, verlieren Sie das -march=nativeund es wird überall funktionieren, wenn Sie Folgendes tun : gcc -Q --help=target.
Oleg Kokorin
@Oleg - Das klingt nach einem Fehler in GCC 5. Das Problem ist in GCC 7 nicht vorhanden.
jww
111

Verwenden Sie zum Anzeigen von Befehlszeilenflags:

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

Wenn Sie möchten, dass die Compiler- / Precompiler-Definitionen durch bestimmte Parameter festgelegt werden, gehen Sie folgendermaßen vor:

echo | gcc -dM -E - -march=native
elias
quelle
1
Diese Antwort verdient ebenso viele positive Stimmen wie die akzeptierte, um insbesondere aufzulisten, was nativewirklich gleichbedeutend ist.
Iwillnotexist Idonotexist
4
Wenn ich also eine native Kompilierung durchführen möchte, sollte ich sowohl dem Compiler als auch den Definitionen UND den Argumenten einen Feed geben. oder reichen die argumente aus?
Hanshenrik
25

Es sollte sein ( -###ist ähnlich -v):

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

Anzeigen der "echten" nativen Flags für gcc.

Sie können sie mit einem Befehl "klarer" erscheinen lassen:

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

und Sie können Flags mit -mno- * entfernen mit:

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

Wenn Sie herausfinden möchten, wie eine nicht native Cross-Kompilierung eingerichtet wird, fand ich dies nützlich:

Auf dem Zielcomputer

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

Verwenden Sie dies dann auf der Build-Maschine:

% gcc -march=core-avx-i ...
Mark Lakata
quelle
Dies beinhaltet leider nicht alle Flags.
Baptiste Wicht
@BaptisteWicht gibt es Flags, die -march = native enthalten, dass -march = core-avx-i in diesem Fall nicht würde, oder welche Flags? Vielen Dank!
Rogerdpack
2
@rogerdpack Auf diesem Computer (Sandybridge) aktiviert March = Sandybridge AVX nicht (weiß nicht warum), während March = Native dies tut. Ein weiterer wichtiger Unterschied ist, dass Cache-Größen nur mit März = native extrahiert werden
Baptiste Wicht
1
@BaptisteWicht, das seltsam ist, scheint hier zu funktionieren (denke ich): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1aber Cache-Größen scheinen nicht vorhanden zu sein.
Rogerdpack
7

Ich werde meine zwei Cent in diese Frage werfen und eine etwas ausführlichere Erweiterung von Elias 'Antwort vorschlagen. Ab gcc 4.6 gcc -march=native -v -E - < /dev/nullsendet das Ausführen von eine zunehmende Menge an Spam in Form überflüssiger -mno-*Flags aus. Folgendes wird diese entfernen:

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

Ich habe die Richtigkeit jedoch nur auf zwei verschiedenen CPUs (Intel Core2 und AMD Phenom) überprüft. Daher empfehle ich, auch das folgende Skript auszuführen, um sicherzustellen, dass alle diese -mno-*Flags sicher entfernt werden können.

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

Ich habe keinen Unterschied zwischen gcc -march=native -v -E - < /dev/nullund gcc -march=native -### -E - < /dev/nullaußer einigen angegebenen Parametern gefunden - und Parametern, die keine Sonderzeichen enthalten, daher bin ich mir nicht sicher, unter welchen Umständen dies einen wirklichen Unterschied macht.

Beachten Sie schließlich, dass dies --march=nativein gcc 4.2 eingeführt wurde, bevor es sich nur um ein nicht erkanntes Argument handelt.

Daniel Santos
quelle
Schön, dieser Blick hat auch die Cache-Größen
Rogerdpack
gcc Version 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-schmutzig) gibt zurück: Fehler: unbekannte Architektur `native '
Oleg Kokorin
Oleg: Welchen Bogen benutzt du? Es kann sein, dass "native" nur auf einigen Architekturen unterstützt wird.
Daniel Santos