GCC: in che modo marcia è diversa da mtune?


88

Ho provato a pulire la pagina man di GCC per questo, ma ancora non l'ho capito, davvero.

Qual è la differenza tra -marche -mtune?

Quando si usa solo -march, contro entrambi? È mai possibile solo -mtune?

Risposte:


97

Se si utilizza, -marchGCC sarà libero di generare istruzioni che funzionano sulla CPU specificata, ma (in genere) non sulle CPU precedenti nella famiglia di architetture.

Se usi solo -mtune, il compilatore genererà codice che funziona su uno qualsiasi di essi, ma favorirà le sequenze di istruzioni che vengono eseguite più velocemente sulla CPU specifica che hai indicato. es. impostare l'euristica di srotolamento del ciclo in modo appropriato per quella CPU.


-march=fooimplica a -mtune=foomeno che non specifichi anche un diverso -mtune. Questo è uno dei motivi per cui usare -marchè meglio che abilitare semplicemente opzioni come -mavxsenza fare nulla per l'ottimizzazione.

Avvertenza: -march=nativesu una CPU che GCC non riconosce in modo specifico, abiliterà comunque nuovi set di istruzioni che GCC può rilevare, ma lascerà -mtune=generic. Usa un GCC abbastanza nuovo che conosca la tua CPU se vuoi che faccia un buon codice.


10
Non risponde se ha senso usarli entrambi o se mtune è ridondante se impostato sullo stesso valore.
Pavel Šimerda

12
@ PavelŠimerda Intuitivamente la risposta è implicita nella definizione delle 2 caratteristiche. Inoltre, la documentazione afferma esplicitamente che marchimplica mtune. Quindi, le risposte alle tue obiezioni sono rispettivamente no e sì.
underscore_d

Grazie per averlo spiegato in modo così elegante! Lo rendi facile da capire.
Rahim Khoja

5
Le persone hanno bisogno di un tl; dr: usa -march se lo esegui SOLO sul tuo processore, usa -mtune se vuoi che sia sicuro per altri processori.
j riv

3
Gli utenti devono anche capire che i compilatori più vecchi (rilasciati prima che alcune CPU non esistessero) possono dare come risultato una combinazione ottimale mtunee diversa march. Questo post del blog illumina questo punto con gli altri: lemire.me/blog/2018/07/25/…
qneill

53

Questo è quello che ho cercato su Google:

L' -march=Xopzione prende un nome di CPU Xe consente a GCC di generare codice che utilizza tutte le funzionalità di X. Il manuale di GCC spiega esattamente quali nomi di CPU significano quali famiglie e caratteristiche di CPU.

Poiché le funzionalità vengono solitamente aggiunte, ma non rimosse, un binario compilato con -march=Xverrà eseguito su CPU X, ha buone possibilità di funzionare su CPU più recenti di X, ma quasi sicuramente non verrà eseguito su qualcosa di più vecchio di X. Alcuni set di istruzioni (3DNow !, immagino?) Potrebbero essere specifici per un particolare fornitore di CPU, utilizzarli probabilmente ti consentirà di ottenere binari che non funzionano su CPU concorrenti, più recenti o meno.

L' -mtune=Yopzione ottimizza il codice generato per essere eseguito più velocemente Yrispetto ad altre CPU su cui potrebbe essere eseguito. -march=Ximplica -mtune=X. -mtune=Ynon sovrascriverà -march=X, quindi, ad esempio, probabilmente non ha senso -march=core2e -mtune=i686- il tuo codice non verrà eseguito su qualcosa di più vecchio di core2comunque, a causa di -march=core2, quindi perché sulla Terra vorresti ottimizzare per qualcosa di più vecchio (meno ricco di funzionalità) di core2? -march=core2 -mtune=haswellha più senso: non utilizzare alcuna funzionalità oltre a ciò che core2fornisce (che è ancora molto di più di ciò che -march=i686ti dà!), ma ottimizza il codice per haswellCPU molto più recenti , non per core2.

C'è anche -mtune=generic. genericfa in modo che GCC produca il codice che funziona meglio sulle attuali CPU (significato delle genericmodifiche da una versione di GCC a un'altra). Ci sono voci sui forum Gentoo che -march=X -mtune=genericproducono codice che gira più velocemente Xdel codice prodotto da -march=X -mtune=X(o semplicemente -march=X, come -mtune=Xè implicito). Non ho idea se questo sia vero o no.

Generalmente, a meno che tu non sappia esattamente di cosa hai bisogno, sembra che la soluzione migliore sia specificare -march=<oldest CPU you want to run on>e -mtune=generic( -mtune=genericè qui per contrastare l'implicito -mtune=<oldest CPU you want to run on>, perché probabilmente non vuoi ottimizzare per la CPU più vecchia). O semplicemente -march=native, se mai funzionerai solo sulla stessa macchina su cui costruisci.


4
Ma se usi -march=native, potresti volerlo specificare -mtune=X, perché l'impostazione predefinita è ancora -mtune=generic, come discusso qui: lemire.me/blog/2018/07/25/…
Roland Weber

@RolandWeber: Ciò accade solo se usi un GCC troppo vecchio per conoscere la tua CPU. -march=nativeimplica tune=nativeche va bene se usi un GCC che conosce la tua CPU. Quell'articolo presenta solo il caso negativo. Le versioni più recenti di GCC migliorano il codice in generale, specialmente quando si usano nuove istruzioni come AVX2 e AVX-512. E avere impostazioni di ottimizzazione (come l'euristica di srotolamento del ciclo) progettate per la tua CPU è un vantaggio decisivo. Quindi, se ti interessano abbastanza le prestazioni da utilizzare queste opzioni, usa un nuovo GCC, almeno uno che conosca la tua CPU, preferibilmente l'attuale versione stabile.
Peter Cordes

Fa schifo che GCC non possa fare di meglio che tune=genericper un nuovo membro della stessa famiglia di microarchitettura, specialmente qualcosa come Kaby Lake che è letteralmente identico alla microarchitettura Skylake. Ma penso che abbia ancora una famiglia / un passo diverso, quindi un GCC che conosceva solo Skylake e anziani potrebbe non riconoscerlo per la messa a punto.
Peter Cordes
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.