Si vous utilisez, -march
GCC 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=foo
implique -mtune=foo
sauf si vous spécifiez également un autre -mtune
. C'est l'une des raisons pour lesquelles il -march
vaut mieux utiliser que simplement activer des options, comme -mavx
sans rien faire pour le réglage.
Attention: -march=native
sur 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.
march
impliquemtune
. Ainsi, les réponses à vos objections sont respectivement non et oui.mtune
et différentesmarch
. Ce billet de blog éclaire ce point avec les autres: lemire.me/blog/2018/07/25/…Voici ce que j'ai recherché sur Google:
L'
-march=X
option prend un nom de CPUX
et permet à GCC de générer du code qui utilise toutes les fonctionnalités deX
. 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=X
fonctionnera sur le processeurX
, a de bonnes chances de fonctionner sur des processeurs plus récents queX
, mais il ne fonctionnera presque certainement pas sur des processeurs plus anciens queX
. 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=Y
option règle le code généré pour qu'il s'exécute plus rapidementY
que sur les autres processeurs sur lesquels il pourrait s'exécuter.-march=X
implique-mtune=X
.-mtune=Y
ne remplacera pas-march=X
, donc, par exemple, cela n'a probablement aucun sens-march=core2
et-mtune=i686
- votre code ne fonctionnera pas sur quelque chose de plus ancien que decore2
toute 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=haswell
Cela a plus de sens: n'utilisez aucune fonctionnalité au-delà de ce quecore2
fournit (ce qui est encore beaucoup plus que ce que-march=i686
vous donne!), mais optimisez le code pour deshaswell
processeurs beaucoup plus récents , pas pourcore2
.Il y a aussi
-mtune=generic
.generic
permet à GCC de produire du code qui fonctionne le mieux sur les processeurs actuels (signification desgeneric
changements d'une version de GCC à une autre). Il y a des rumeurs sur les forums Gentoo qui-march=X -mtune=generic
produisent du code plus rapideX
que le code produit par-march=X -mtune=X
do (ou tout simplement-march=X
, comme cela-mtune=X
est 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=generic
est 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.la source
-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/…-march=native
impliquetune=native
trè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.tune=generic
pour 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.