website logo
Auteur
avatar
thellier

Forum » » Création-Développement » » GCC: Pourquoi l'option -O3 est un faux ami (optimisation)


Posté : 04-04-2014 17:04 icone du post

Hello

Depuis quelque temps j'ai mis une série de test (benchmarks) pour mesurer la vitesse de mon Microbe3D
Le résultat le plus essentiel étant celui que j'appelle "TPF50" qui est le "temps par frame calculé sur 50 frame"
Par exemple je notais le 15 mars sur une PartyGirl immobile que j'obtenais un TPF50 de 63 ou 64 millisecondes
(donc 1000/64 = 15.6 frames par secondes)
Je programme, je rajoute qques trucs légérs, je rajoute le support arexx sous os4, je teste ça marche

Et paf je regarde mon TP50 : 67 !!! arghh
Aussi le binaire a beaucoup grossi : 482 KO à 566 KO

Mais d'où ça vient ?
De l'option d'optimisation -O3 de gcc

En effet avec O3 on inline les fonctions
"inliner" c'est GCC qui au lieu d'appeler une fonction (un sous programme) met directement les instructions de la fonction à cet endroit
Normalement ça accélére le programme puisqu'il n' y plus de saut dans un sous programme ailleurs mais juste des instructions à ce même endroit

par exemple

/*=================================================================*/
/* Normalize: normalize a vector */
inline void Normalize(Vertex3D *c)
{
register float size;

size = (float)sqrt(c->x * c->x + c->y * c->y + c->z * c->z);
if(size==0) return;
c->x /= size;
c->y /= size;
c->z /= size;
}
/*=================================================================*/
void NormalizeVertices(Vertex3D *V,ULONG nbrepoints)
{
register ULONG n;

for(n=0;n!=nbrepoints;n++)
Normalize(&V[n]);

}
/*=================================================================*/

La fonction Normalize() n'est alors plus appelé dans NormalizeVertices (ce qui prend un certain temps) mais les instructions de Normalize() y sont directement inclues
Normalize() devient donc une macro

Bref normalement -O3 qui inline ce serait bien...

Mais là avec mon wrapper arexx il y avait un gros problème :
c'étais un wrapper qui appelait chaque fonction de l'api Microbe3D (45 fonctions en tout) depuis une fonction arexx
Donc chaque (grosse) fonction de l'api Microbe3D était dupliquée dans la fonction arexx
===> augmentation conséquente de taille du binaire
===> binaire plus gros ==> utilise mal le cache cpu

Conclusion: -O3 c'est pas bien il vaut mieux rajouter "inline" devant les vrais fonctions à inliner (comme celle servant de fonction mathématiques dans des boucles de calculs) et ne plus laisser faire GCC en prenant plutôt -O2
Les bon programmeurs le savent certainement déjà , moi aussi je le savais aussi un peu mais je n'avais jamais réalisé que les progs ayant des wrappers (cad pleins de fonctions vides servant juste à appeler une autre fonction) pouvait etre autant impacté

avec -O2 le binaire revient à 347 KO et refais 64 millisencondes par frame avec le support arexx

Alain













Message édité par : thellier / 07-04-2014 14:48

Cet article provient de Le site des utilisateurs francophones actuels et futurs d'AmigaOS 4.x
https://amiga-ng.org/viewtopic.php?topic=1843&forum=14