GCC: en quoi mars est-il différent de mtune?

87

J'ai essayé de nettoyer la page de manuel de GCC pour cela, mais je ne comprends toujours pas, vraiment.

Quelle est la différence entre -marchet -mtune?

Quand utilise-t-on juste -march, contre les deux? Est-il jamais possible de juste -mtune?

Jameson
la source

Réponses:

97

Si vous utilisez, -marchGCC sera libre de générer des instructions qui fonctionnent sur le processeur spécifié, mais (généralement) pas sur les processeurs antérieurs de la famille d'architecture.

Si vous utilisez simplement -mtune, le compilateur générera du code qui fonctionnera sur n'importe lequel d'entre eux, mais favorisera les séquences d'instructions qui s'exécutent le plus rapidement sur le processeur spécifique que vous avez indiqué. par exemple, définir l'heuristique de déroulement de boucle de manière appropriée pour cette CPU.


-march=fooimplique -mtune=foosauf si vous spécifiez également un autre -mtune. C'est l'une des raisons pour lesquelles il -marchvaut mieux utiliser que simplement activer des options, comme -mavxsans rien faire pour le réglage.

Attention: -march=nativesur un CPU que GCC ne reconnaît pas spécifiquement, il activera toujours de nouveaux jeux d'instructions que GCC pourra détecter, mais qui le quittera -mtune=generic. Utilisez un GCC assez nouveau qui connaît votre CPU si vous voulez qu'il fasse du bon code.

James Youngman
la source
10
Ne répond pas s'il est judicieux d'utiliser les deux ou si mtune est redondant lorsqu'il est défini sur la même valeur.
Pavel Šimerda
12
@ PavelŠimerda Intuitivement, la réponse est implicite dans la définition des 2 fonctionnalités. En outre, la documentation indique explicitement que cela marchimplique mtune. Ainsi, les réponses à vos objections sont respectivement non et oui.
underscore_d
Merci d'avoir expliqué cela si élégamment! Vous le rendez facile à comprendre.
Rahim Khoja
5
Les gens ont besoin d'un tl; dr: Utilisez -march si vous l'exécutez UNIQUEMENT sur votre processeur, utilisez -mtune si vous le voulez sûr pour d'autres processeurs.
j riv
3
Les utilisateurs doivent également comprendre que les compilateurs plus anciens (publiés avant que certains CPU n'existaient) peuvent entraîner des combinaisons optimales mtuneet différentes march. Ce billet de blog éclaire ce point avec les autres: lemire.me/blog/2018/07/25/…
qneill
52

Voici ce que j'ai recherché sur Google:

L' -march=Xoption prend un nom de CPU Xet permet à GCC de générer du code qui utilise toutes les fonctionnalités de X. Le manuel GCC explique exactement quels noms de CPU signifient quelles familles et fonctionnalités de CPU.

Parce que les fonctionnalités sont généralement ajoutées, mais pas supprimées, un binaire construit avec -march=Xfonctionnera sur le processeur X, a de bonnes chances de fonctionner sur des processeurs plus récents que X, mais il ne fonctionnera presque certainement pas sur des processeurs plus anciens que X. Certains jeux d'instructions (3DNow !, je suppose?) Peuvent être spécifiques à un fournisseur de processeur particulier, leur utilisation vous permettra probablement d'obtenir des binaires qui ne fonctionnent pas sur des processeurs concurrents, plus récents ou non.

L' -mtune=Yoption règle le code généré pour qu'il s'exécute plus rapidement Yque sur les autres processeurs sur lesquels il pourrait s'exécuter. -march=Ximplique -mtune=X. -mtune=Yne remplacera pas -march=X, donc, par exemple, cela n'a probablement aucun sens -march=core2et -mtune=i686- votre code ne fonctionnera pas sur quelque chose de plus ancien que de core2toute façon, à cause de -march=core2, alors pourquoi diable voudriez-vous optimiser pour quelque chose de plus ancien (moins fonctionnel) que core2? -march=core2 -mtune=haswellCela a plus de sens: n'utilisez aucune fonctionnalité au-delà de ce que core2fournit (ce qui est encore beaucoup plus que ce que -march=i686vous donne!), mais optimisez le code pour des haswellprocesseurs beaucoup plus récents , pas pour core2.

Il y a aussi -mtune=generic. genericpermet à GCC de produire du code qui fonctionne le mieux sur les processeurs actuels (signification des genericchangements d'une version de GCC à une autre). Il y a des rumeurs sur les forums Gentoo qui -march=X -mtune=genericproduisent du code plus rapide Xque le code produit par -march=X -mtune=Xdo (ou tout simplement -march=X, comme cela -mtune=Xest sous-entendu). Aucune idée si cela est vrai ou non.

En général, à moins que vous ne sachiez exactement ce dont vous avez besoin, il semble que le meilleur cours soit de spécifier -march=<oldest CPU you want to run on>et -mtune=generic( -mtune=genericest là pour contrer l'implicite -mtune=<oldest CPU you want to run on>, car vous ne voulez probablement pas optimiser pour le processeur le plus ancien). Ou simplement -march=native, si jamais vous n'allez exécuter que sur la même machine sur laquelle vous construisez.

LRN
la source
4
Mais si vous utilisez -march=native, vous voudrez peut-être le spécifier -mtune=X, car la valeur par défaut est toujours -mtune=generic, comme discuté ici: lemire.me/blog/2018/07/25/…
Roland Weber
@RolandWeber: Cela ne se produit que si vous utilisez un GCC trop ancien pour connaître votre CPU. -march=nativeimplique tune=nativetrès bien si vous utilisez un GCC qui connaît votre CPU. Cet article ne présente que le mauvais cas. Les nouvelles versions de GCC font un meilleur code en général, en particulier lors de l'utilisation de nouvelles instructions comme AVX2 et AVX-512. Et avoir des paramètres de réglage (comme l'heuristique de déroulement de boucle) conçus pour votre CPU est un avantage certain. Donc, si vous vous souciez suffisamment des performances pour utiliser ces options, utilisez un nouveau GCC, au moins un qui connaît votre CPU, de préférence la version stable actuelle.
Peter Cordes le
Ça craint que GCC ne puisse pas faire mieux que tune=genericpour un nouveau membre de la même famille de microarchitecture, en particulier quelque chose comme Kaby Lake qui est littéralement identique à Skylake microarchitecturalement. Mais je pense qu'il a toujours une famille / un pas différent, donc un GCC qui ne connaissait que Skylake et plus pourrait ne pas le reconnaître pour le réglage.
Peter Cordes le