276 votes

Est optimisation niveau - O3 dangereux en g ++ ?

J’ai entendu provenant de diverses sources (mais surtout d’un de mes collègues), cette compilation avec un niveau d’optimisation de en est en quelque sorte « dangereux » et devrait être évitée en général sauf si s’est avéré nécessaire.

Est-ce vrai et si oui, pourquoi ? Dois je simplement s’en tenir à `` ?

268voto

PlasmaHH Points 8426

Dans les premiers jours de la gcc (2.8 etc.) et à l'époque de egcs, et redhat 2.96-O3 été assez buggé parfois. Mais c'est plus d'une décennie, et -O3 n'est pas bien différent de celui des autres niveaux d'optimisations (en buggyness).

Il n'a cependant tendance à révéler des cas où les gens s'appuient sur un comportement indéfini, en raison du recours plus strictement les règles, et en particulier le coin des affaires, de la / les langue(s).

Comme une note personnelle, je suis en cours d'exécution d'un logiciel de production dans le secteur financier depuis de nombreuses années maintenant, avec -O3 et n'ont pas encore rencontré un bug qui n'aurait pas été là si je l'aurais utilisé -O2.

Par demande populaire, voici un ajout:

-O3 et en particulier des indicateurs supplémentaires comme -funroll-loops (non activé par -O3) peut parfois conduire à plus de code machine généré. Dans certaines circonstances (par exemple sur un cpu avec exceptionnellement faible L1 cache d'instructions), cela peut provoquer un ralentissement en raison de tout le code, par exemple, de certains boucle interne maintenant ne figure plus dans L1I. Généralement gcc essaie très dur pour ne pas générer autant de code, mais depuis qu'il a habituellement optimise le cas générique, ce qui peut arriver. Options particulièrement sujettes à ce (comme le déroulement de la boucle) ne sont pas normalement inclus dans -O3 et sont marqués en conséquence dans la page de manuel. En tant que tel, il est généralement une bonne idée d'utiliser -O3 pour la génération de code rapide, et seulement tomber en arrière-O2 ou -Os (qui tente d'optimiser la taille du code) le cas échéant (par exemple, lorsqu'un générateur de profils indique L1I manque).

Si vous voulez prendre de l'optimisation de l'extrême, vous pouvez le tordre dans gcc via --param les coûts associés à certaines optimisations. En outre noter que la gcc a maintenant la possibilité de mettre des attributs à des fonctions de contrôle de l'optimisation des paramètres de ces fonctions, ainsi, lorsque vous trouvez que vous avez un problème avec-O3 dans une fonction (ou que vous voulez essayer des indicateurs justement pour cette fonction), vous n'avez pas besoin de compiler le fichier entier ou même de l'ensemble du projet avec O2.

otoh, que il semble que les soins doivent être prises lors de l'utilisation -Ofast, qui stipule:

-Ofast permet à tous -O3 optimisations. Il permet également aux optimisations qui ne sont pas valables pour tous les types programmes compatibles.

ce qui me fait conclure que -O3 est destiné à être pleinement conformes aux normes.

53voto

Zack Points 44583

Ce qui est dit dans Neel réponse, mais pas clairement ou assez fortement:

Dans ma quelque peu mouvementée de l'expérience, en appliquant -O3 à la totalité d'un programme presque toujours , il est plus lent (par rapport à l' -O2), parce qu'il s'allume agressif déroulement de la boucle et de l'in-lining que le programme ne rentrent plus dans le cache d'instructions. Pour les plus grands programmes, cela peut aussi être vrai pour -O2 par rapport à l' -Os!

Du profil d'emploi pour -O3 , après profilage de votre programme, vous l'appliquer manuellement une petite poignée de fichiers contenant des critiques de boucles internes qui bénéficient effectivement de ces agressive de l'espace à la vitesse de compromis. Avec très récente de GCC, je pense que le brillant nouveau lien-temps profil guidée à l'optimisation de la mode peut appliquer de manière sélective l' -O3 optimisations à chaud des fonctions -- efficacement l'automatisation de ce processus.

17voto

neel Points 612

-O3 option active des optimisations plus chers, comme la fonctionnalité inline, en outre à toutes les optimisations des niveaux inférieurs '-O2' et '-O1'. Le '-O3' niveau d’optimisation peut augmenter la vitesse de l’exécutable qui en résulte, mais peut aussi augmenter sa taille. Dans certaines circonstances où ces optimisations ne sont pas favorables, cette option pourrait en fait rendre un programme plus lent.

2voto

borisbn Points 2301

Il y a quelques temps, je suis entré en collision avec l'optimisation. Il y avait une carte PCI, qui la représentait registres (pour commande et de données) par des cellules de mémoire. Mon chauffeur mappé phisique adresse de la mémoire à niveau de l'application du pointeur et le donna à appelé processus, qui a travaillé avec elle comme ceci:

unsigned int * pciMemory;
askDriverForMapping( & pciMemory );
...
pciMemory[ 0 ] = someCommandIdx;
pciMemory[ 0 ] = someCommandLength;
for ( int i = 0; i < sizeof( someCommand ); i++ )
    pciMemory[ 0 ] = someCommand[ i ];

J'ai été étonnant pourquoi la carte n'agissent pas comme prévu. Et seulement quand j'ai vu l'assembleur, j'ai compris que le compilateur a écrit seulement someCommand[ the last ] en pciMemory, en omettant toutes les précédentes écritures.

En conclusion: être précis et attentif à l'optimisation )))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X