2017-02-28 3 views
0

Spécifiquement j'utilise gcc -O2 -g, mais il peut s'appliquer à n'importe quel compilateur. Lorsque je compile pour l'optimisation avec des informations de débogage pour le profilage, un problème est que le compilateur inline et optimise la fonction entière, donc à partir d'une fonction de vingt lignes avec quelques appels, je me retrouve avec seulement quatre ou cinq lignes gauche dans le code, et un numéro de ligne a réussi à collecter environ 75% du code, donc je trouve difficile de dire où est exactement le goulot d'étranglement. Permettez-moi d'illustrer:Force le compilateur pour optimiser la fonction dans les morceaux

void foo() 
{ 
    // code... 
    foo = doThingOne(); // Gets inlined 
    bar = doThingTwo(); // Gets inlined 

    externalFunction(foo, bar); // Doesn't get inlined 
    // code... 
} 

Maintenant, quand je regarde ma sortie profileur je vois quelque chose comme ça - le pourcentage étant le temps passé sur chaque ligne post-optimisation:

void foo() 
10%{ 
     // code... 
3%  foo = doThingOne(baz); // Gets inlined 
     bar = doThingTwo(wibble); // Gets inlined 

75% externalFunction(foo, bar); // Doesn't get inlined 
12% // code... 
    } 

Le 3% pourrait être juste quelque chose comme push baz, avec la majorité du code mis en évidence dans la ligne pour l'appel de externalFunction(). Je pourrais bien sûr faire doThingOne() un externe, mais qui est tout à fait beaucoup d'efforts, donc ce serait bien si je pouvais dire quelque chose comme:

void foo() 
{ 
    // code... 
    foo = doThingOne(); // Gets inlined 
#pragma optimisation_barrier 
    bar = doThingTwo(); // Gets inlined 

#pragma optimisation_barrier 
    externalFunction(foo, bar); // Doesn't get inlined 
    // code... 
} 

Cela briserait l'optimisation en trois morceaux, pour que je puisse clairement voir les poids relatifs des trois fonctions dans un état proche du code courant final réel. Est-ce qu'une telle chose existe?

+0

Qu'est-ce que 'externalFunction'? Son corps est-il visible dans l'unité de traduction actuelle? –

+0

@BasileStarynkevitch non, son corps n'est pas visible. –

+1

Ensuite, il ne peut pas être inline, sauf si vous compilez et * liez * le * programme entier * avec '-flto -O2' –

Répondre

2

Si votre externalFunction est déclarée comme externe, défini dans une autre unité de traduction, et non pas comme static inline il ne sera pas inline, en compilant et de liaison (par exemple avec gcc -flto -O2 sauf si vous demandez pour l'optimisation du temps lien immeuble avec make CC='gcc -flto -O2') votre programme ou bibliothèque entier. Voir aussi this.

GCC a pragmas for optimizations:

#pragma GCC optimize ("O2") 

(vous pourriez peut-être essayer #pragma GCC optimize("O3")avant votre corps de la fonction)

Ce serait briser le optimzation en trois morceaux

Mais optim La ialisation fonctionne sur des pièces plus grandes, au moins sur des corps entiers. Je crois que penser en termes de «morceaux» à optimiser n'a pas beaucoup de sens. Enfin, l'optimisation pourrait confondre les informations de profilage (et les informations de débogage dans DWARF). Alors, prenez-le avec soin et comparez tout le programme (ou au moins une fonction complète de haut niveau de votre programme). Je prendrais avec prudence le chiffre de 75%.

BTW, inlining ne signifie pas toujours accélération (en raison de CPU caches, un plus grand code est cache hostile). Peut-être que vous pourriez augmenter votre -finline-limit=setting. Mais vous pourriez perdre la performance!

En outre, compiler votre code avec -S -O2 -fverbose-asm et regarder dans le code assembleur généré dans le fichier .s, vous verrez alors ce qui a été inline.