Ich habe versucht, die GCC-Manpage dafür zu bereinigen, verstehe es aber immer noch nicht.
Was ist der Unterschied zwischen -march
und -mtune
?
Wann verwendet man nur -march
gegen beide? Ist es jemals möglich, nur -mtune
?
Antworten:
Wenn Sie verwenden, kann -march
GCC Anweisungen generieren, die auf der angegebenen CPU funktionieren, jedoch (normalerweise) nicht auf früheren CPUs in der Architekturfamilie.
Wenn Sie nur verwenden -mtune
, generiert der Compiler Code, der auf jedem von ihnen funktioniert, bevorzugt jedoch Befehlssequenzen, die auf der von Ihnen angegebenen CPU am schnellsten ausgeführt werden. zB Einstellen der für diese CPU geeigneten Heuristik zum Abrollen von Schleifen.
-march=foo
impliziert, es -mtune=foo
sei denn, Sie geben auch eine andere an -mtune
. Dies ist ein Grund, warum die Verwendung -march
besser ist, als nur Optionen zu aktivieren, -mavx
ohne etwas gegen die Optimierung zu tun.
Vorsichtsmaßnahme: -march=native
Auf einer CPU, die GCC nicht speziell erkennt, werden weiterhin neue Befehlssätze aktiviert, die GCC erkennen kann, die jedoch verlassen werden -mtune=generic
. Verwenden Sie ein ausreichend neues GCC, das sich mit Ihrer CPU auskennt, wenn Sie möchten, dass sie guten Code erstellt.
march
impliziert mtune
. Die Antworten auf Ihre Einwände lauten also Nein bzw. Ja.
mtune
und march
Kombinationen führen können. Dieser Blog-Beitrag beleuchtet diesen Punkt mit den anderen: lemire.me/blog/2018/07/25/…
Das habe ich gegoogelt:
Die -march=X
Option verwendet einen CPU-Namen X
und ermöglicht es GCC, Code zu generieren, der alle Funktionen von verwendet X
. Das GCC-Handbuch erklärt genau, welche CPU-Namen welche CPU-Familien und -Funktionen bedeuten.
Da Funktionen normalerweise hinzugefügt, aber nicht entfernt werden, -march=X
läuft eine mit erstellte Binärdatei auf der CPU X
, hat eine gute Chance, auf CPUs ausgeführt zu werden, die neuer als sind X
, aber fast sicher nicht auf etwas älterem als X
. Bestimmte Befehlssätze (3DNow!, Denke ich?) Sind möglicherweise spezifisch für einen bestimmten CPU-Hersteller. Wenn Sie diese verwenden, erhalten Sie wahrscheinlich Binärdateien, die nicht auf konkurrierenden CPUs, neueren oder anderen, ausgeführt werden.
Die -mtune=Y
Option optimiert den generierten Code so, dass er schneller ausgeführt wird Y
als auf anderen CPUs, auf denen er möglicherweise ausgeführt wird. -march=X
impliziert -mtune=X
. -mtune=Y
wird nicht überschrieben -march=X
, so macht es zum Beispiel wahrscheinlich keinen Sinn -march=core2
und -mtune=i686
- Ihr Code wird auf nichts älter als core2
sowieso ausgeführt, weil -march=core2
warum sollten Sie also für etwas älteres (weniger funktionsfähiges) als core2 optimieren? -march=core2 -mtune=haswell
Sinnvoller: Verwenden Sie keine Funktionen, die über das hinausgehen core2
(was immer noch viel mehr ist als das, -march=i686
was Sie bieten!), sondern optimieren Sie den Code für viel neuere haswell
CPUs, nicht für core2
.
Es gibt auch -mtune=generic
. generic
Lässt GCC Code produzieren, der auf aktuellen CPUs am besten läuft (dh generic
Änderungen von einer Version von GCC zu einer anderen). Es gibt Gerüchte in Gentoo-Foren, -march=X -mtune=generic
die Code produzieren, der schneller läuft X
als Code, der von do produziert wird -march=X -mtune=X
(oder einfach -march=X
, wie -mtune=X
impliziert). Keine Ahnung, ob das stimmt oder nicht.
Wenn Sie nicht genau wissen, was Sie benötigen, scheint es im Allgemeinen am besten zu sein, -march=<oldest CPU you want to run on>
und anzugeben -mtune=generic
( -mtune=generic
um dem Impliziten entgegenzuwirken -mtune=<oldest CPU you want to run on>
, da Sie wahrscheinlich nicht für die älteste CPU optimieren möchten). Oder einfach -march=native
, wenn Sie jemals nur auf demselben Computer ausgeführt werden, auf dem Sie aufbauen.
-march=native
, möchten Sie möglicherweise angeben -mtune=X
, da der Standard immer noch ist -mtune=generic
, wie hier beschrieben: lemire.me/blog/2018/07/25/…
-march=native
Dies ist in tune=native
Ordnung, wenn Sie einen GCC verwenden, der sich mit Ihrer CPU auskennt. Dieser Artikel präsentiert nur den schlimmen Fall. Neuere GCC-Versionen bieten im Allgemeinen besseren Code, insbesondere wenn neue Anweisungen wie AVX2 und AVX-512 verwendet werden. Und Optimierungseinstellungen (wie z. B. Heuristiken zum Abwickeln von Schleifen) für Ihre CPU sind ein klares Plus. Wenn Sie sich also genug um die Leistung kümmern, um diese Optionen nutzen zu können, verwenden Sie einen neuen GCC, mindestens einen, der Ihre CPU kennt, vorzugsweise die aktuelle stabile Version.
tune=generic
ein neueres Mitglied derselben Mikroarchitekturfamilie, insbesondere etwas wie Kaby Lake, das buchstäblich mit der Mikroarchitektur von Skylake identisch ist. Aber ich denke, es hat immer noch eine andere Familie / Stufe, so dass ein GCC, der nur über Skylake und älter Bescheid wusste, es möglicherweise nicht für die Abstimmung erkennt.