"Michel Michaud" writes:J'ose une question : est-ce vraiment important ou utile cette
optimisation ? N'y a-t-il pas des choses plus importantes qui
manquent dans gcc (ou g++) ?
Comme ?
Il me semble que si le compilateur
peut optimiser du code ordinaire, il pourra optimiser du code
où j'aurais enlevé explicitement la récursivité (en tout ou en
partie) et obtenir un résultat meilleur que l'optimisation
complète de la récursivité qu'il aurait pu faire.
Ce raisonnement n'est pas nouveau. Mais le fait est qu'il y a ce
mouvement, donc certains pensent que c'est important -- pusque dans
la liste de ceux que je vois implémenter cela, c'est sur des
contrats spécificques.
J'ai peut-être
une mauvaise idée des endroits où la récursivité est utile, mais
il me semble qu'annoncer de l'optimisation de la récursivité par
le compilateur, c'est un peu prendre la chance que les gens
codent récursivement ce qui n'a pas besoin d'être récursif en
pensant faire mieux que la version non récursive...
Ou que les gens codent recursivement pour des besoins de clarté de
correction et veulent que le compilateur se débrouille pour
optimiser.
À quoi sert un compilateur ?
Je ne suis pas sûr, qu'il y a ait Une Seule Réponse,
"Michel Michaud" <mm@gdzid.com> writes:
J'ose une question : est-ce vraiment important ou utile cette
optimisation ? N'y a-t-il pas des choses plus importantes qui
manquent dans gcc (ou g++) ?
Comme ?
Il me semble que si le compilateur
peut optimiser du code ordinaire, il pourra optimiser du code
où j'aurais enlevé explicitement la récursivité (en tout ou en
partie) et obtenir un résultat meilleur que l'optimisation
complète de la récursivité qu'il aurait pu faire.
Ce raisonnement n'est pas nouveau. Mais le fait est qu'il y a ce
mouvement, donc certains pensent que c'est important -- pusque dans
la liste de ceux que je vois implémenter cela, c'est sur des
contrats spécificques.
J'ai peut-être
une mauvaise idée des endroits où la récursivité est utile, mais
il me semble qu'annoncer de l'optimisation de la récursivité par
le compilateur, c'est un peu prendre la chance que les gens
codent récursivement ce qui n'a pas besoin d'être récursif en
pensant faire mieux que la version non récursive...
Ou que les gens codent recursivement pour des besoins de clarté de
correction et veulent que le compilateur se débrouille pour
optimiser.
À quoi sert un compilateur ?
Je ne suis pas sûr, qu'il y a ait Une Seule Réponse,
"Michel Michaud" writes:J'ose une question : est-ce vraiment important ou utile cette
optimisation ? N'y a-t-il pas des choses plus importantes qui
manquent dans gcc (ou g++) ?
Comme ?
Il me semble que si le compilateur
peut optimiser du code ordinaire, il pourra optimiser du code
où j'aurais enlevé explicitement la récursivité (en tout ou en
partie) et obtenir un résultat meilleur que l'optimisation
complète de la récursivité qu'il aurait pu faire.
Ce raisonnement n'est pas nouveau. Mais le fait est qu'il y a ce
mouvement, donc certains pensent que c'est important -- pusque dans
la liste de ceux que je vois implémenter cela, c'est sur des
contrats spécificques.
J'ai peut-être
une mauvaise idée des endroits où la récursivité est utile, mais
il me semble qu'annoncer de l'optimisation de la récursivité par
le compilateur, c'est un peu prendre la chance que les gens
codent récursivement ce qui n'a pas besoin d'être récursif en
pensant faire mieux que la version non récursive...
Ou que les gens codent recursivement pour des besoins de clarté de
correction et veulent que le compilateur se débrouille pour
optimiser.
À quoi sert un compilateur ?
Je ne suis pas sûr, qu'il y a ait Une Seule Réponse,
Oui, j'ai compris un peu mieux par ton autre message. J'avoue
que si l'on convertit du code d'un autre langage en C et que
cet autre langage met de l'avant un style pro-récursivité, ce
sera pratique.
Oui, j'ai compris un peu mieux par ton autre message. J'avoue
que si l'on convertit du code d'un autre langage en C et que
cet autre langage met de l'avant un style pro-récursivité, ce
sera pratique.
Oui, j'ai compris un peu mieux par ton autre message. J'avoue
que si l'on convertit du code d'un autre langage en C et que
cet autre langage met de l'avant un style pro-récursivité, ce
sera pratique.
"Gabriel Dos Reis" a écrit dans le message
news:"Alain Naigeon" writes:
Merci pour ta réponse, il me faut un peu de temps pour
la digérer. Mais j'ai tout de même une question immédiate :
void f()
{
if( false)
{ /*
...
*/
}
Est-ce que le langage autorise une optimisation à :
void f() { }
?
(ou à rien du tout)
"Gabriel Dos Reis" <gdr@integrable-solutions.net> a écrit dans le message
news: m3y8tdr3l1.fsf@uniton.integrable-solutions.net...
"Alain Naigeon" <anaigeon@free.fr> writes:
Merci pour ta réponse, il me faut un peu de temps pour
la digérer. Mais j'ai tout de même une question immédiate :
void f()
{
if( false)
{ /*
...
*/
}
Est-ce que le langage autorise une optimisation à :
void f() { }
?
(ou à rien du tout)
"Gabriel Dos Reis" a écrit dans le message
news:"Alain Naigeon" writes:
Merci pour ta réponse, il me faut un peu de temps pour
la digérer. Mais j'ai tout de même une question immédiate :
void f()
{
if( false)
{ /*
...
*/
}
Est-ce que le langage autorise une optimisation à :
void f() { }
?
(ou à rien du tout)
Ta fonction ne contient pas de comportement visible, et n'influe pas sur
des comportements visibles ailleurs. Le compilateur peut en faire ce
qu'il veut, pourvu que ce qu'il fait n'a pas de comportement visible, et
n'influe pas sur le comportement visible par ailleurs. Il peut donc ôter
la fonction complètement, ou le remplacer par une boucle qui dure une
heure. (Côté qualité de l'implémentation, tous les choix ne sont pas
égaux, mais la norme n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland, au
Ta fonction ne contient pas de comportement visible, et n'influe pas sur
des comportements visibles ailleurs. Le compilateur peut en faire ce
qu'il veut, pourvu que ce qu'il fait n'a pas de comportement visible, et
n'influe pas sur le comportement visible par ailleurs. Il peut donc ôter
la fonction complètement, ou le remplacer par une boucle qui dure une
heure. (Côté qualité de l'implémentation, tous les choix ne sont pas
égaux, mais la norme n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland, au
Ta fonction ne contient pas de comportement visible, et n'influe pas sur
des comportements visibles ailleurs. Le compilateur peut en faire ce
qu'il veut, pourvu que ce qu'il fait n'a pas de comportement visible, et
n'influe pas sur le comportement visible par ailleurs. Il peut donc ôter
la fonction complètement, ou le remplacer par une boucle qui dure une
heure. (Côté qualité de l'implémentation, tous les choix ne sont pas
égaux, mais la norme n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland, au
a écrit
[...]Ta fonction ne contient pas de comportement visible, et n'influe pas
sur des comportements visibles ailleurs. Le compilateur peut en
faire ce qu'il veut, pourvu que ce qu'il fait n'a pas de
comportement visible, et n'influe pas sur le comportement visible
par ailleurs. Il peut donc ôter la fonction complètement, ou le
remplacer par une boucle qui dure une heure. (Côté qualité de
l'implémentation, tous les choix ne sont pas égaux, mais la norme
n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland,
au moins):
void f(){}
Ou mieux avec :
int douze(){return 12;}
et l'appel :
...
int VarInt;
int a = 45;
int b = 13;
VarInt = a + (b * douze()) + (b - (douze()*douze()));
...
douze() est définie juste avant le main() d'où se fait l'appel.
Le seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Dans tous les autres cas, la fonction est toujours appelée (le code
machine est généré). et je ne me suis pas fait avoir par le mode debug
(erreur fréquente dans les EDI qui fait que certains affirment que la
fonction n'est pas inlinée, alors qu'elle l'est dans la release). Un
jour, j'ai même vérifié avec un debugger code machine.
Je n'ai jamais pu faire disparaitre l'appel à une fonction non inline,
aussi inutile soit-elle. Je n'ai pas testé le if(false)f();. A
l'occasion.. Sauf erreur, le Pascal de Delphi est plus radical dans
ses optimisations. J'ai interprété au débuit comme ça :
- si le programmeur demande inline, il ne demande pas un appel.
- dans tous les autres cas, il demande un appel, il faut le respecter.
<kanze@gabi-soft.fr> a écrit
[...]
Ta fonction ne contient pas de comportement visible, et n'influe pas
sur des comportements visibles ailleurs. Le compilateur peut en
faire ce qu'il veut, pourvu que ce qu'il fait n'a pas de
comportement visible, et n'influe pas sur le comportement visible
par ailleurs. Il peut donc ôter la fonction complètement, ou le
remplacer par une boucle qui dure une heure. (Côté qualité de
l'implémentation, tous les choix ne sont pas égaux, mais la norme
n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland,
au moins):
void f(){}
Ou mieux avec :
int douze(){return 12;}
et l'appel :
...
int VarInt;
int a = 45;
int b = 13;
VarInt = a + (b * douze()) + (b - (douze()*douze()));
...
douze() est définie juste avant le main() d'où se fait l'appel.
Le seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Dans tous les autres cas, la fonction est toujours appelée (le code
machine est généré). et je ne me suis pas fait avoir par le mode debug
(erreur fréquente dans les EDI qui fait que certains affirment que la
fonction n'est pas inlinée, alors qu'elle l'est dans la release). Un
jour, j'ai même vérifié avec un debugger code machine.
Je n'ai jamais pu faire disparaitre l'appel à une fonction non inline,
aussi inutile soit-elle. Je n'ai pas testé le if(false)f();. A
l'occasion.. Sauf erreur, le Pascal de Delphi est plus radical dans
ses optimisations. J'ai interprété au débuit comme ça :
- si le programmeur demande inline, il ne demande pas un appel.
- dans tous les autres cas, il demande un appel, il faut le respecter.
a écrit
[...]Ta fonction ne contient pas de comportement visible, et n'influe pas
sur des comportements visibles ailleurs. Le compilateur peut en
faire ce qu'il veut, pourvu que ce qu'il fait n'a pas de
comportement visible, et n'influe pas sur le comportement visible
par ailleurs. Il peut donc ôter la fonction complètement, ou le
remplacer par une boucle qui dure une heure. (Côté qualité de
l'implémentation, tous les choix ne sont pas égaux, mais la norme
n'exige pas une qualité minimum.)
J'ai fait des tests avec des fonctions inutiles (compilateur Borland,
au moins):
void f(){}
Ou mieux avec :
int douze(){return 12;}
et l'appel :
...
int VarInt;
int a = 45;
int b = 13;
VarInt = a + (b * douze()) + (b - (douze()*douze()));
...
douze() est définie juste avant le main() d'où se fait l'appel.
Le seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Dans tous les autres cas, la fonction est toujours appelée (le code
machine est généré). et je ne me suis pas fait avoir par le mode debug
(erreur fréquente dans les EDI qui fait que certains affirment que la
fonction n'est pas inlinée, alors qu'elle l'est dans la release). Un
jour, j'ai même vérifié avec un debugger code machine.
Je n'ai jamais pu faire disparaitre l'appel à une fonction non inline,
aussi inutile soit-elle. Je n'ai pas testé le if(false)f();. A
l'occasion.. Sauf erreur, le Pascal de Delphi est plus radical dans
ses optimisations. J'ai interprété au débuit comme ça :
- si le programmeur demande inline, il ne demande pas un appel.
- dans tous les autres cas, il demande un appel, il faut le respecter.
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wroteLe seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Ça dépend du compilateur. Sans démander une certaine optimisation, c'est
probable qu'elle ne soit jamais générée en ligne. Avec les meilleurs
compilateurs, si le profiler dit que c'est là que ça coince, le
compilateur génèrera la fonction en ligne, même si l'appel est virtuel,
et même si la définition de la fonction se trouve dans une autre module.
(D'accord, d'aussi bons compilateurs sont rares. Mais ils existent.)
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote
Le seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Ça dépend du compilateur. Sans démander une certaine optimisation, c'est
probable qu'elle ne soit jamais générée en ligne. Avec les meilleurs
compilateurs, si le profiler dit que c'est là que ça coince, le
compilateur génèrera la fonction en ligne, même si l'appel est virtuel,
et même si la définition de la fonction se trouve dans une autre module.
(D'accord, d'aussi bons compilateurs sont rares. Mais ils existent.)
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wroteLe seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.
Ça dépend du compilateur. Sans démander une certaine optimisation, c'est
probable qu'elle ne soit jamais générée en ligne. Avec les meilleurs
compilateurs, si le profiler dit que c'est là que ça coince, le
compilateur génèrera la fonction en ligne, même si l'appel est virtuel,
et même si la définition de la fonction se trouve dans une autre module.
(D'accord, d'aussi bons compilateurs sont rares. Mais ils existent.)