fonctions inline, théorie et pratique

Le
Korchkidu
Bonjour à tous,

les fonctions inline sont en théorie faites pour rendre le code plus
rapide. Pourtant, il me semble me souvenir d'une discussion qui
soutenait que de toute façon, ça ne servait à rien car le compilateur
faisait ce qu'il voulait au final. Est-ce vrai ? Dans ce cas, à quoi
ça sert de "inliner" des fonctions (à part faire une siggestion au
compilateur) ? Est-ce qu'en inlinant correctement ses fonctions on
arrive à des gains de performances en pratique ?

Meilleures salutations.
K.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Michael Doubez
Le #19840911
On 28 juil, 08:42, Korchkidu
les fonctions inline sont en théorie faites pour rendre le code plus
rapide. Pourtant, il me semble me souvenir d'une discussion qui
soutenait que de toute façon, ça ne servait à rien car le compilate ur
faisait ce qu'il voulait au final. Est-ce vrai ? Dans ce cas, à quoi
ça sert de "inliner" des fonctions (à part faire une siggestion au
compilateur) ? Est-ce qu'en inlinant correctement ses fonctions on
arrive à des gains de performances en pratique ?



Voir FAQ Lite
http://www.parashift.com/c++-faq-lite/inline-functions.html
En français (vieille version):
http://jlecomte.ifrance.com/c++/c++-faq-lite/inline-functions-fr.html

--
Michael
Korchkidu
Le #19840901
On Jul 28, 9:19 am, Michael Doubez
On 28 juil, 08:42, Korchkidu
> les fonctions inline sont en théorie faites pour rendre le code plus
> rapide. Pourtant, il me semble me souvenir d'une discussion qui
> soutenait que de toute façon, ça ne servait à rien car le compila teur
> faisait ce qu'il voulait au final. Est-ce vrai ? Dans ce cas, à quoi
> ça sert de "inliner" des fonctions (à part faire une siggestion au
> compilateur) ? Est-ce qu'en inlinant correctement ses fonctions on
> arrive à des gains de performances en pratique ?

Voir FAQ Litehttp://www.parashift.com/c++-faq-lite/inline-functions.html
En français (vieille version):http://jlecomte.ifrance.com/c++/c++-faq-l ite/inline-functions-fr.html



Merci pour ta réponse... ça, c'est ce que j'appelle la théorie. Mais
en pratique ?

K.
James Kanze
Le #19841111
On Jul 28, 8:42 am, Korchkidu
les fonctions inline sont en théorie faites pour rendre le
code plus rapide. Pourtant, il me semble me souvenir d'une
discussion qui soutenait que de toute façon, ça ne servait à
rien car le compilateur faisait ce qu'il voulait au final.
Est-ce vrai ? Dans ce cas, à quoi ça sert de "inliner" des
fonctions (à part faire une siggestion au compilateur) ?
Est-ce qu'en inlinant correctement ses fonctions on arrive à
des gains de performances en pratique ?



La motivation derrière les fonctions inline, c'est de pouvoir
donner au compilateur d'avantage d'informations, de lui dire que
cette fonction risque d'être appelée souvent, dans des boucles
critiques, et que ça pourrait être utile à l'optimisation de la
générer en ligne. C'est l'*intention* des auteurs du C++ que le
compilateur le génère en ligne s'il peut, et s'il n'est pas
capable de faire mieux que le programmeur. Dans ce sens, il est
comme register, à la difference près qu'aujourd'hui, prèsque
tous les compilateurs peuvent réelement faire mieux que le
programmeur en ce qui concerne register, tandis qu'il n'y a que
fort peu qui y arrive en ce qui concerne inline.

De point de vue formelle, évidemment, ce n'est qu'une
recommendation au compilateur. Pour diverses raisons techniques,
on ne peut jamais lui imposer la génération en ligne, et la
norme (même C) a toujours permis au compilateur tout ce qui ne
modifie le comportement visible du programme, y compris la
génération en ligne des fonctions, déclarées inline ou non.
Formellement, tout ce que inline fait, c'est de permettre (et
exiger) la définition de la fonction dans toutes les unités de
traduction qui l'utilisent. Mais il n'y a pas que le formel :
formellement, il n'y a rien non plus qui interdit au compilateur
de générer une boucle vide de cinq minutes d'attente à chaque
point-virgule. Dans la pratique, il y a quelque chose qui
s'appelle la qualité de l'implémentation, et la qualité de
l'implémentation prend bien en compte l'intention, et non
seulement la lettre de la norme. Certains compilateurs (très
peu) font assez d'analyse pour mieux savoir que le programmeur
ce qui doit être inline ; ils traitent l'inline exactement comme
n'importe quelle autre fonction. Et certaines fonctions posent
des problèmes à la génération en ligne (des fonctions
récursives, par exemple) -- elles ne seront pas générées en
ligne, quoique tu fasses. Pour la reste, c'est une question de
la qualité de l'implémentation.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mathias Gaunard
Le #19842111
On 28 juil, 08:42, Korchkidu
Dans ce cas, à quoi
ça sert de "inliner" des fonctions (à part faire une siggestion au
compilateur) ?



À avoir un linkage faible, ce qui permet d'avoir la définition de la
fonction dans plusieurs unités de traduction.
Sinon, ce serait une erreur.

Note que les fonctions membres définies dans la définition d'une
classe sont également inline de manière implicite, sinon cela
causerait des erreurs à l'édition de liens.
pjb
Le #19843361
James Kanze
[...] Certains compilateurs (très
peu) font assez d'analyse pour mieux savoir que le programmeur
ce qui doit être inline ; ils traitent l'inline exactement comme
n'importe quelle autre fonction. Et certaines fonctions posent
des problèmes à la génération en ligne (des fonctions
récursives, par exemple) -- elles ne seront pas générées en
ligne, quoique tu fasses. Pour la reste, c'est une question de
la qualité de l'implémentation.



Si c'est une recursion terminale, et que le compilateur sait
l'optimiser, alors il peut facilement mettre la fonction en ligne,
puisqu'elle n'est plus qu'un boucle.

--
__Pascal Bourguignon__
Falk Tannhäuser
Le #19851311
Pascal J. Bourguignon schrieb:
James Kanze
[...] Certains compilateurs (très
peu) font assez d'analyse pour mieux savoir que le programmeur
ce qui doit être inline ; ils traitent l'inline exactement comme
n'importe quelle autre fonction. Et certaines fonctions posent
des problèmes à la génération en ligne (des fonctions
récursives, par exemple) -- elles ne seront pas générées en
ligne, quoique tu fasses. Pour la reste, c'est une question de
la qualité de l'implémentation.



Si c'est une récursion terminale, et que le compilateur sait
l'optimiser, alors il peut facilement mettre la fonction en ligne,
puisqu'elle n'est plus qu'une boucle.



GCC 4.3.2 le fait à partir du niveau d'optimisation -O2, tandis que GCC 3.4.4 ne le faisait pas - on n'arrête pas la progrès !
Je suis sous Cygwin et j'ai essayé avec la fonction

unsigned factorial(unsigned n)
{
return n <= 1 ? 1 : n * factorial(n - 1);
}

Falk
Gabriel Dos Reis
Le #19851661
Falk Tannhäuser
| Pascal J. Bourguignon schrieb:
| > James Kanze | >> [...] Certains compilateurs (très
| >> peu) font assez d'analyse pour mieux savoir que le programmeur
| >> ce qui doit être inline ; ils traitent l'inline exactement comme
| >> n'importe quelle autre fonction. Et certaines fonctions posent
| >> des problèmes à la génération en ligne (des foncti ons
| >> récursives, par exemple) -- elles ne seront pas génér ées en
| >> ligne, quoique tu fasses. Pour la reste, c'est une question de
| >> la qualité de l'implémentation.
| >
| > Si c'est une récursion terminale, et que le compilateur sait
| > l'optimiser, alors il peut facilement mettre la fonction en ligne,
| > puisqu'elle n'est plus qu'une boucle.
|
| GCC 4.3.2 le fait à partir du niveau d'optimisation -O2, tandis que
| GCC 3.4.4 ne le faisait pas - on n'arrête pas la progrès !

GCC optimisait la recursivité terminale depuis bien longtemps (du moin s,
quand j'étais encore étudiant).

| Je suis sous Cygwin et j'ai essayé avec la fonction
|
| unsigned factorial(unsigned n)
| {
| return n <= 1 ? 1 : n * factorial(n - 1);
| }

Ceci n'est pas une recursivité terminale.

-- Gaby
James Kanze
Le #19852401
On Jul 30, 2:57 am, Gabriel Dos Reis
Falk Tannhäuser


> Pascal J. Bourguignon schrieb:
> > James Kanze > >> [...] Certains compilateurs (très
> >> peu) font assez d'analyse pour mieux savoir que le programmeur
> >> ce qui doit être inline ; ils traitent l'inline exactement comme
> >> n'importe quelle autre fonction. Et certaines fonctions posent
> >> des problèmes à la génération en ligne (des fonctions
> >> récursives, par exemple) -- elles ne seront pas générées en
> >> ligne, quoique tu fasses. Pour la reste, c'est une question de
> >> la qualité de l'implémentation.



> > Si c'est une récursion terminale, et que le compilateur sait
> > l'optimiser, alors il peut facilement mettre la fonction en ligne,
> > puisqu'elle n'est plus qu'une boucle.



> GCC 4.3.2 le fait à partir du niveau d'optimisation -O2, tandis que
> GCC 3.4.4 ne le faisait pas - on n'arrête pas la progrès !



GCC optimisait la recursivité terminale depuis bien longtemps
(du moins, quand j'étais encore étudiant).



> Je suis sous Cygwin et j'ai essayé avec la fonction



> unsigned factorial(unsigned n)
> {
> return n <= 1 ? 1 : n * factorial(n - 1);
> }



Ceci n'est pas une recursivité terminale.



Je ne me rappelle plus des détails, mais il me semble que si la
profondeur est finie, et connue au point de l'appel, g++ génère
en ligne aussi, en duplicant le code, jusqu'à certain niveau.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jean-Marc Bourguet
Le #19854001
Olivier Miakinen
Le 30/07/2009 02:57, Gabriel Dos Reis a écrit :

GCC optimisait la recursivité terminale depuis bien longtemps (du moins,
quand j'étais encore étudiant).

| Je suis sous Cygwin et j'ai essayé avec la fonction
|
| unsigned factorial(unsigned n)
| {
| return n <= 1 ? 1 : n * factorial(n - 1);
| }

Ceci n'est pas une recursivité terminale.



Si je ne me trompe pas, la version avec récursivité terminale serait :

unsigned factorial(unsigned n, unsigned res = 1)
{
return n <= 1 ? res : factorial(n - 1, n * res);
}



Pas tout à fait (le calcul est fait dans l'autre sens, vu l'associativité
de la multiplication ça ne change pas le résultat ici).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Olivier Miakinen
Le #19853921
Le 30/07/2009 02:57, Gabriel Dos Reis a écrit :

GCC optimisait la recursivité terminale depuis bien longtemps (du moins,
quand j'étais encore étudiant).

| Je suis sous Cygwin et j'ai essayé avec la fonction
|
| unsigned factorial(unsigned n)
| {
| return n <= 1 ? 1 : n * factorial(n - 1);
| }

Ceci n'est pas une recursivité terminale.



Si je ne me trompe pas, la version avec récursivité terminale serait :

unsigned factorial(unsigned n, unsigned res = 1)
{
return n <= 1 ? res : factorial(n - 1, n * res);
}
Publicité
Poster une réponse
Anonyme