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?

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 .


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

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'

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 ...

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.