Je connais assez bien le drapeau GCC -O3, mais en quoi il diffère de -Os. Dans quelle situation préférerions-nous un plutôt qu'un autre?
La documentation GCC décrit très explicitement ce que font ces options.
-O3 essaie d'optimiser le code très lourd pour la performance. Il inclut toutes les optimisations incluses dans -O2, ainsi que d'autres.
-Os, d’autre part, demande à GCC d’optimiser la taille. Il permet toutes les optimisations -O2 qui n'augmentent pas la taille de l'exécutable, puis bascule également certains indicateurs d'optimisation pour réduire davantage la taille de l'exécutable.
Notez que mes descriptions ont été délibérément un peu vagues - lisez la documentation de GCC pour une discussion plus détaillée sur les indicateurs activés pour l'un ou l'autre niveau d'optimisation.
Je pense que les niveaux d’optimisation -O * ne sont que cela - des niveaux d’optimisation distincts, distincts. Cela n’a pas vraiment de sens de les mélanger, car deux niveaux activeront ou laisseront de côté les drapeaux que l’autre laissera volontairement de côté ou activera (respectivement). Si vous voulez mélanger et faire correspondre (vous ne voulez probablement pas réellement le faire, sauf si vous avez une très bonne raison de vouloir un ensemble spécifique de drapeaux), vous feriez mieux de lire la documentation et de mélanger et faire correspondre les drapeaux à chaque niveau. permet à la main.
Je pense que je relierai également cet article du Wiki Gentoo Linux, qui traite des indicateurs d'optimisation relatifs à la construction des packages pour le système d'exploitation. Évidemment, tout cela n’est pas applicable, mais il contient encore quelques informations intéressantes - par exemple:
Compiler avec -O3 n'est pas un moyen sûr d'améliorer les performances. En fait, dans de nombreux cas, il peut ralentir un système en raison de fichiers binaires plus volumineux et d'une utilisation accrue de la mémoire. -O3 est également connu pour casser plusieurs paquets. Par conséquent, l'utilisation de -O3 n'est pas recommandée.
Selon cet article, -O2 est, la plupart du temps, "aussi bon que" -O3 et est plus sûr à utiliser en ce qui concerne les sorties exécutables brisées.
Je suggère de lire la documentation de GCC. -O3 est destiné à obtenir un code rapide (même au prix de pertes de code), tandis que -Os
optimise la taille du code généré.
Il y a des tonnes d'autres (obscurs) GCC indicateurs d'optimisation (par exemple, -fgcse-sm
), dont beaucoup ne sont pas activés même à -O3
.
Vous pouvez également être intéressé par -flto (pour Optimisation de Link-Time) à utiliser, par exemple, par exemple. -O3
ou -Os
, à la fois à la compilation et à lien. Ensuite, voir aussi cette réponse .
Enfin, veillez à utiliser la dernière version de GCC (4,8 actuellement à la fin de 2013), car GCC améliore considérablement ses optimisations.
Vous voudrez peut-être aussi utiliser -mtune = native (au moins pour x86).
Et vous pourriez même écrire votre propre passe d'optimisation, spécifique à vos propres bibliothèques et API, en utilisant éventuellement le plugin MELT .
Comme réponse de CmdrMoozy }, vous préférerez peut-être utiliser -O2
over -O3
(mais notez que les versions récentes de GCC ont beaucoup amélioré leur -O3
, de sorte que la citation Gentoo -recommending contre -O3
et en faveur de -O2
devient moins pertinent.).
En outre, comme le montre ce SlashDot-ed papier empilé (de Xi Wang, Nickolai Zeldovich, M. Frans Kaashoek et Armando Solar-Lezama), de nombreux programmes ne sont pas entièrement conformes à la norme C et ne sont pas satisfaits (et comportement incorrect) lorsque certaines optimisations valide sont effectuées. _ { Comportement indéfini } _ est un sujet délicat.
BTW, notez que l'utilisation de -O3
rend généralement votre temps de compilation beaucoup plus long, et apporte souvent (mais pas toujours) au plus quelques pour cent de performances en plus que -O2
ou même -O1
.... (c'est encore pire avec -flto
). C'est pourquoi I l'utilise rarement.
Ça dépend. Avez-vous besoin d'optimiser la vitesse ou la taille?
-O3
Optimiser encore plus. -O3 active toutes les optimisations spécifiées par -O2 ainsi que les fonctions -finline-functions, -funswitch-loops, - commune prédictive, -fgcse-après-rechargement, -ftree-loop-vectorize, -ftree-slp-vectorize, -fvect-cost-model, -ftree-partial-pre et -fipa-cp-clone-O0
Réduisez le temps de compilation et faites en sorte que le débogage produise les résultats attendus. C'est la valeur par défaut.-Os
Optimiser pour la taille. -Os active toutes les optimisations -O2 qui n'augmentent généralement pas la taille du code. Il effectue également d'autres optimisations conçu pour réduire la taille du code.
-Os Désactive les indicateurs d'optimisation suivants:
-falign-functions
-falign-jumps
-falign-loops
-falign-labels
-freorder-blocks
-freorder-blocks-and-partition
-fprefetch-loop-arrays
En fait, -O est un raccourci pour une longue liste d'optimisations indépendantes. Si vous ne savez pas ce dont vous avez besoin, choisissez simplement -O3.
-O3 optimise la vitesse, tandis que -Os optimise l'espace. Cela signifie que -O3 vous donnera un exécutable rapide, mais il peut être assez volumineux, et -Os vous donne un exécutable plus petit, mais peut-être plus lent.
L’utilisation rationnelle de l’espace et du temps est généralement un compromis. Les algorithmes plus rapides ont tendance à prendre plus de place, alors que les algorithmes sur place (qui n'augmentent pas l'utilisation de l'espace) ont tendance à être moins efficaces.
Habituellement, les ordinateurs modernes ont beaucoup d’espace mémoire, donc -O3 est préférable. Cependant, si vous programmez quelque chose avec peu de RAM (comme un petit périphérique), vous préférerez peut-être -Os