Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

optimisation non souhaitée

10 réponses
Avatar
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/

10 réponses

Avatar
Jean-Marc Bourguet
Manuel Pégourié-Gonnard writes:

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
Avatar
JKB
Le Mon, 3 Dec 2012 09:56:06 +0100 (CET),
Manuel Pégourié-Gonnard écrivait :
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
Avatar
Marc Boyer
Le 03-12-2012, Manuel Pégourié-Gonnard a écrit :

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
Avatar
Dominique MICOLLET
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.
Avatar
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,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Avatar
Bruno Ducrot
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 ?
Avatar
espie
In article ,
Bruno Ducrot wrote:
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.
Avatar
Bruno Ducrot
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 ?
Avatar
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?
Avatar
espie
In article ,
moebius eye wrote:
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.