optimisation non souhaitée

Le
Manuel Pégourié-Gonnard
Bonjour,

considérons le fragment de code suivant :

int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];

q[0] = add(a, b);
q[1] = dbl(a);

return q[c];
}

Ais-je la garantie qu'à chaque appel de add_or_dbl(), chacune des deux
fonctions add() et dbl() sera appelée, et que le compilo ne va pas
optimiser le corps de add_or_dbl() en quelque chose comme

return c ? dbl(a) : add(a, b);

où il n'y aurait donc qu'une seule des deux fonctions appellée ?

Est-ce que ça change quelque chose si les deux fonctions add() et dbl()
sont static ? Dans ce cas, le compilo peut il me semble les inliner,
mais une fois inlinées, peut-il supprimer leur corps, ou plus précisément
rendre son exécution conditionnelle ?

Dans le contexte qui m'intéresse, les fonctions add() et dbl() sont
coûteuses en temps d'exécution, mais ont des coûts différents, et ce que
je veux, c'est que add_or_dbl() ait un temps d'exécution indépendant de
la valeur de c (ou plus précisément, que la séquence d'opérations
coûteuses soit la même indépendament de la valeur de c). J'ai vu ce
genre de code conseillé pour répondre à ce besoin, et je ne suis pas sûr
de comprendre ce qui garanti que ça marche, et encore moins quelles sont
les limites.

Merci d'avance pour vos lumières !

--
Manuel Pégourié-Gonnard - http://people.math.jussieu.fr/~mpg/
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #25015682
Manuel Pégourié-Gonnard
Bonjour,

considérons le fragment de code suivant :

int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];

q[0] = add(a, b);
q[1] = dbl(a);

return q[c];
}

Ais-je la garantie qu'à chaque appel de add_or_dbl(), chacune des de ux
fonctions add() et dbl() sera appelée, et que le compilo ne va pas
optimiser le corps de add_or_dbl() en quelque chose comme

return c ? dbl(a) : add(a, b);

où il n'y aurait donc qu'une seule des deux fonctions appellée ?



Le compilateur doit faire comme si; ca ne doit pas changer les effets
visibles d'un programme conforme. Si le code de add et dbl est visible
et qu'il n'y a pas d'effet de bord, il peut le faire. S'il decide
d'inliner les fonctions, ca ne serait meme pas surprenant qu'il le
fasse.

Dans le contexte qui m'intéresse, les fonctions add() et dbl() sont
coûteuses en temps d'exécution, mais ont des coûts diffà ©rents, et ce
que je veux, c'est que add_or_dbl() ait un temps d'exécution
indépendant de la valeur de c (ou plus précisément, que la séquence
d'opérations coûteuses soit la même indépendament de la valeur de
c). J'ai vu ce genre de code conseillé pour répondre à ce besoin, et
je ne suis pas sûr de comprendre ce qui garanti que ça marche, et
encore moins quelles sont les limites.



Il y a peu de garanties. Si tu les mets dans une autre unite de
compilation, il y a plus de chance que ca ne se passe pas; mais avec les
optimisations au link, ce n'est meme pas garanti.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
JKB
Le #25015672
Le Mon, 3 Dec 2012 09:56:06 +0100 (CET),
Manuel Pégourié-Gonnard
Bonjour,

considérons le fragment de code suivant :

int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];

q[0] = add(a, b);
q[1] = dbl(a);

return q[c];
}

Ais-je la garantie qu'à chaque appel de add_or_dbl(), chacune des deux
fonctions add() et dbl() sera appelée, et que le compilo ne va pas
optimiser le corps de add_or_dbl() en quelque chose comme

return c ? dbl(a) : add(a, b);

où il n'y aurait donc qu'une seule des deux fonctions appellée ?

Est-ce que ça change quelque chose si les deux fonctions add() et dbl()
sont static ? Dans ce cas, le compilo peut il me semble les inliner,
mais une fois inlinées, peut-il supprimer leur corps, ou plus précisément
rendre son exécution conditionnelle ?

Dans le contexte qui m'intéresse, les fonctions add() et dbl() sont
coûteuses en temps d'exécution, mais ont des coûts différents, et ce que
je veux, c'est que add_or_dbl() ait un temps d'exécution indépendant de
la valeur de c (ou plus précisément, que la séquence d'opérations
coûteuses soit la même indépendament de la valeur de c). J'ai vu ce
genre de code conseillé pour répondre à ce besoin, et je ne suis pas sûr
de comprendre ce qui garanti que ça marche, et encore moins quelles sont
les limites.

Merci d'avance pour vos lumières !



Bonjour,

Personnellment, je ne m'y fierais pas trop. Dans un tel cas, j'ai
pour habitude d'horodater le début et la fin de l'appel de fonction
et de compléter par un nanosleep(). Au pire, tu peux initialiser la
valeur maximale du délai en faisant un premier tour à vide.

Attention, le délai de calibration est à calculer sur le temps CPU.

Cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Marc Boyer
Le #25016142
Le 03-12-2012, Manuel Pégourié-Gonnard
Je propose l'usage du mot clé volatile.


int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];


volatile bool x=c;

q[0] = add(a, b);
q[1] = dbl(a);



return q[x];
}




--
À mesure que les inégalités regressent, les attentes se renforcent.
François Dubet
Dominique MICOLLET
Le #25016362
Bonjour

Manuel Pégourié-Gonnard a écrit :
J'ai vu ce
genre de code conseillé pour répondre à ce besoin, et je ne sui s pas sûr
de comprendre ce qui garanti que ça marche, et encore moins quelles sont
les limites.



Dans gcc, il est possible de supprimer l'optimisation pour un fichier s ource
avec l'option -O0 : une solution pourrait donc être d'isoler add_or_d bl dans
un fichier séparé.

Cordialement

Dominique.
Bruno Ducrot
Le #25033302
On 03-12-2012, Manuel Pégourié-Gonnard wrote:
Bonjour,

considérons le fragment de code suivant :

int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];

q[0] = add(a, b);
q[1] = dbl(a);

return q[c];
}

Ais-je la garantie qu'à chaque appel de add_or_dbl(), chacune des deux
fonctions add() et dbl() sera appelée, et que le compilo ne va pas
optimiser le corps de add_or_dbl() en quelque chose comme

return c ? dbl(a) : add(a, b);

où il n'y aurait donc qu'une seule des deux fonctions appellée ?



Si les deux fonctions add() et dbl() ne font pas partie de la même unité de
compilation, alors le compilateur doit les appeller dans l'ordre spécifié,
puisqu'il ne peut savoir si ces fonctions-là auront des effets de bord.

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Bruno Ducrot
Le #25033312
On 03-12-2012, Jean-Marc Bourguet wrote:
Dans le contexte qui m'intéresse, les fonctions add() et dbl() sont
coûteuses en temps d'exécution, mais ont des coûts différents, et ce
que je veux, c'est que add_or_dbl() ait un temps d'exécution
indépendant de la valeur de c (ou plus précisément, que la séquence
d'opérations coûteuses soit la même indépendament de la valeur de
c). J'ai vu ce genre de code conseillé pour répondre à ce besoin, et
je ne suis pas sûr de comprendre ce qui garanti que ça marche, et
encore moins quelles sont les limites.



Il y a peu de garanties. Si tu les mets dans une autre unite de
compilation, il y a plus de chance que ca ne se passe pas; mais avec les
optimisations au link, ce n'est meme pas garanti.



J'ai cru que vous aviez tort, mais lorsque je lis plus attentivement
5.1.2.3.10 il se trouve qu'un tel comportement est effectivement
permis par la norme.

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
espie
Le #25033632
In article Bruno Ducrot
On 03-12-2012, Manuel Pégourié-Gonnard wrote:
Bonjour,

considérons le fragment de code suivant :

int add(int, int);
int dbl(int);

int add_or_dbl(int a, int b, bool c)
{
int q[2];

q[0] = add(a, b);
q[1] = dbl(a);

return q[c];
}

Ais-je la garantie qu'à chaque appel de add_or_dbl(), chacune des deux
fonctions add() et dbl() sera appelée, et que le compilo ne va pas
optimiser le corps de add_or_dbl() en quelque chose comme

return c ? dbl(a) : add(a, b);

où il n'y aurait donc qu'une seule des deux fonctions appellée ?



Si les deux fonctions add() et dbl() ne font pas partie de la même unité de
compilation, alors le compilateur doit les appeller dans l'ordre spécifié,
puisqu'il ne peut savoir si ces fonctions-là auront des effets de bord.

A plus,



Non.
Les compilos recents peuvent repasser sur leurs traces pendant l'edition
de liens.

Repete apres moi: tant que le comportement observable est le meme, le
compilo a le droit de faire tout ce qu'il veut pour optimiser le resultat,
meme unite de compilation ou pas.
Bruno Ducrot
Le #25035842
On 08-12-2012, Marc Espie wrote:

Non.
Les compilos recents peuvent repasser sur leurs traces pendant l'edition
de liens.

Repete apres moi: tant que le comportement observable est le meme, le
compilo a le droit de faire tout ce qu'il veut pour optimiser le resultat,
meme unite de compilation ou pas.




Tant que le comportement observable est le même, le compilo a le droit de
faire tout ce qu'il veut pour optimiser le résultat, même unite de compilation
ou pas.

Ceci dit, j'ai déjà rectifié mon erreur dans

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
moebius eye
Le #25105022
On Sat, 8 Dec 2012 07:43:10 +0000 (UTC)
(Marc Espie) wrote:

Repete apres moi: tant que le comportement observable est le meme, le
compilo a le droit de faire tout ce qu'il veut pour optimiser le resultat,
meme unite de compilation ou pas.



Ça veut dire que si tu fais semblant de faire quelque-chose avec le q[0] et le q[1]
avant de return q[c] , il n'aura pas le droit d'optimiser à ce point?
espie
Le #25105052
In article moebius eye
On Sat, 8 Dec 2012 07:43:10 +0000 (UTC)
(Marc Espie) wrote:

Repete apres moi: tant que le comportement observable est le meme, le
compilo a le droit de faire tout ce qu'il veut pour optimiser le resultat,
meme unite de compilation ou pas.



Ça veut dire que si tu fais semblant de faire quelque-chose avec le q[0] et le q[1]
avant de return q[c] , il n'aura pas le droit d'optimiser à ce point?



<Perceval>C'est pas faux!</Perceval>

Je ne suis pas sur que ce que tu dis ait un sens.
Il faudrait mettre du concret derriere tout ca. C'est quoi "faire semblant de
faire quelque chose avec le q[0] et le q[1]" ?

Dans l'immediat, q[0] et q[1] sont non volatile, donc le compilo les voit bien, et il
faut un sacre tour de passe-passe pour "faire semblant", du coup.
Publicité
Poster une réponse
Anonyme