bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
"xylo" a écrit dans le message de news:
gebsn3$gso$bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
Comparer les pointeurs est la solution classique pour determiner le sens de
la copie. J'ai rarement vu des implementations qui "optimisent" en testant
l'egalité. En regle generale, cette comparaison n'est pas gratuite et les
cas d'égalité doivent être assez rares, le seul fait de faire un branchement
est plus couteux qu'une copie de taille non triviale.
Un rapide tour d'horizon donne les observations suivantes:
- glibc (version 2.3.5) ne fait le test QUE pour la version en assembleur
Vax.
- dietlibc fait le test pour la version generique en C de memmove, ce qui
est surprenant puisque cela fait plus de code alors que l'objectif de la
dietlibc est de réduire le code au maximum.
- newlib ne fait jamais le test, ni en C, ni dans les versions optimisées en
assembleur.
Moralité : si tu sais que ton code fait souvent des copies de gros blocs
identiques, utilise une fonction inline qui fait le test et rappelle
memmove. Dans des cas pathologiques, tu peux observer une amelioration.
Mais c'est quand meme une indication de mauvais choix algorithmiques. Comme
d'habitude, les ameliorations algorithmiques seront plus importantes que les
optimisations de bas niveau.
"xylo" <public.jmm@free.fr> a écrit dans le message de news:
gebsn3$gso$4@s1.news.oleane.net...
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
Comparer les pointeurs est la solution classique pour determiner le sens de
la copie. J'ai rarement vu des implementations qui "optimisent" en testant
l'egalité. En regle generale, cette comparaison n'est pas gratuite et les
cas d'égalité doivent être assez rares, le seul fait de faire un branchement
est plus couteux qu'une copie de taille non triviale.
Un rapide tour d'horizon donne les observations suivantes:
- glibc (version 2.3.5) ne fait le test QUE pour la version en assembleur
Vax.
- dietlibc fait le test pour la version generique en C de memmove, ce qui
est surprenant puisque cela fait plus de code alors que l'objectif de la
dietlibc est de réduire le code au maximum.
- newlib ne fait jamais le test, ni en C, ni dans les versions optimisées en
assembleur.
Moralité : si tu sais que ton code fait souvent des copies de gros blocs
identiques, utilise une fonction inline qui fait le test et rappelle
memmove. Dans des cas pathologiques, tu peux observer une amelioration.
Mais c'est quand meme une indication de mauvais choix algorithmiques. Comme
d'habitude, les ameliorations algorithmiques seront plus importantes que les
optimisations de bas niveau.
"xylo" a écrit dans le message de news:
gebsn3$gso$bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments sont
égaux avant d'opérer ? ou faut-il systématiquement vérifier l'égalité des
deux pointeurs avant de l'appeler (dans un soucis d'optimisation) ?
Comparer les pointeurs est la solution classique pour determiner le sens de
la copie. J'ai rarement vu des implementations qui "optimisent" en testant
l'egalité. En regle generale, cette comparaison n'est pas gratuite et les
cas d'égalité doivent être assez rares, le seul fait de faire un branchement
est plus couteux qu'une copie de taille non triviale.
Un rapide tour d'horizon donne les observations suivantes:
- glibc (version 2.3.5) ne fait le test QUE pour la version en assembleur
Vax.
- dietlibc fait le test pour la version generique en C de memmove, ce qui
est surprenant puisque cela fait plus de code alors que l'objectif de la
dietlibc est de réduire le code au maximum.
- newlib ne fait jamais le test, ni en C, ni dans les versions optimisées en
assembleur.
Moralité : si tu sais que ton code fait souvent des copies de gros blocs
identiques, utilise une fonction inline qui fait le test et rappelle
memmove. Dans des cas pathologiques, tu peux observer une amelioration.
Mais c'est quand meme une indication de mauvais choix algorithmiques. Comme
d'habitude, les ameliorations algorithmiques seront plus importantes que les
optimisations de bas niveau.
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments son t
égaux avant d'opérer ?
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments son t
égaux avant d'opérer ?
bonjour,
la fonction memmove contrôle-t-elle que ses deux premiers arguments son t
égaux avant d'opérer ?
On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
On 30 oct, 09:53, xylo <public....@free.fr> wrote:
la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
En news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire » (qui
peut être en fait des ports d'entrée-sortie projetés en mémoire) en
question, si l'on suppose que l'opération WRITE a d'autres effets que le
simple fait de stocker une valeur pour ensuite la restituer par
l'opération
READ.
En news:40da94d6-4998-4c97-9c66-c88f1b31dae3@i20g2000prf.googlegroups.com,
-ed- va escriure:
On 30 oct, 09:53, xylo <public....@free.fr> wrote:
la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire » (qui
peut être en fait des ports d'entrée-sortie projetés en mémoire) en
question, si l'on suppose que l'opération WRITE a d'autres effets que le
simple fait de stocker une valeur pour ensuite la restituer par
l'opération
READ.
En news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire » (qui
peut être en fait des ports d'entrée-sortie projetés en mémoire) en
question, si l'on suppose que l'opération WRITE a d'autres effets que le
simple fait de stocker une valeur pour ensuite la restituer par
l'opération
READ.
Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Antoine Leca a écrit dans: gemsgp$jd3$1@shakotay.alphanet.ch...
En
news:40da94d6-4998-4c97-9c66-c88f1b31dae3@i20g2000prf.googlegroups.com,
-ed- va escriure:
On 30 oct, 09:53, xylo <public....@free.fr> wrote:
la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
En news:gen311$2gg$, Charlie Gordon va
escriure:Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer que
les effets de bord de la description sont bien réalisés. Évidemment, dans le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy() s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique que
les implémenteurs passe outre « l'optimisation » de tester explicitement ce
cas.
Antoine
En news:gen311$2gg$1@registered.motzarella.org, Charlie Gordon va
escriure:
Antoine Leca a écrit dans: gemsgp$jd3$1@shakotay.alphanet.ch...
En
news:40da94d6-4998-4c97-9c66-c88f1b31dae3@i20g2000prf.googlegroups.com,
-ed- va escriure:
On 30 oct, 09:53, xylo <public....@free.fr> wrote:
la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer que
les effets de bord de la description sont bien réalisés. Évidemment, dans le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy() s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique que
les implémenteurs passe outre « l'optimisation » de tester explicitement ce
cas.
Antoine
En news:gen311$2gg$, Charlie Gordon va
escriure:Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer que
les effets de bord de la description sont bien réalisés. Évidemment, dans le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy() s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique que
les implémenteurs passe outre « l'optimisation » de tester explicitement ce
cas.
Antoine
En news:gen311$2gg$, Charlie Gordon va
escriure:Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire
(hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire
plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas
pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à
voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer
que
les effets de bord de la description sont bien réalisés. Évidemment, dans
le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération
memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins
subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy()
s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de
recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour
utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique
que
les implémenteurs passe outre « l'optimisation » de tester explicitement
ce
cas.
En news:gen311$2gg$1@registered.motzarella.org, Charlie Gordon va
escriure:
Antoine Leca a écrit dans: gemsgp$jd3$1@shakotay.alphanet.ch...
En
news:40da94d6-4998-4c97-9c66-c88f1b31dae3@i20g2000prf.googlegroups.com,
-ed- va escriure:
On 30 oct, 09:53, xylo <public....@free.fr> wrote:
la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire
(hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire
plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas
pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à
voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer
que
les effets de bord de la description sont bien réalisés. Évidemment, dans
le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération
memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins
subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy()
s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de
recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour
utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique
que
les implémenteurs passe outre « l'optimisation » de tester explicitement
ce
cas.
En news:gen311$2gg$, Charlie Gordon va
escriure:Antoine Leca a écrit dans: gemsgp$jd3$En
news:,
-ed- va escriure:On 30 oct, 09:53, xylo wrote:la fonction memmove contrôle-t-elle que ses deux premiers arguments
sont égaux avant d'opérer ?
Si les pointeurs sont égaux, à quoi peut bien servir memmove() ?
Rafraîchir la mémoire RAM ?
Ou plus généralement effectuer une opération sur la zone « mémoire »
(qui peut être en fait des ports d'entrée-sortie projetés en
mémoire) en question, si l'on suppose que l'opération WRITE a
d'autres effets que le simple fait de stocker une valeur pour
ensuite la restituer par l'opération READ.
Si tel est le but, il faut utiliser une fonction ad hoc qui déclare le
pointeur vers la zone de memoire avec l'attribut volatile. Utiliser
memmove pour un tel effet de bord n'est pas loisible : on ne sait pas
dans quel ordre la memoire va être lue, écrite, ni combien de fois,
ni même si la mémoire sera lue !
D'après la description de la fonction, la mémoire doit bien être lue et
écrite, au moins dans la machine abstraite. Si l'implémentation permet que
les pointeurs void* adressent des dispositifs projetés en mémoire
(hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser » memmove() au
point de ne pas faire de lecture.
L'ordre n'est pas toujours un problème. Quant au fait de pouvoir faire
plus
d'une lecture ou écriture, c'est une chose à laquelle je n'avais pas
pensée
mais effectivement, il doit être valide pour memove() de lire (resp.
d'écrire) plusieurs fois les objets pointés par s2 (resp. s1) ; reste à
voir
si c'est un problème ; pour rafraîchir la RAM, je pense que non.
Il est en effet possible, et c'est
le sens de la question de l'OP, que memmove teste si la copie est
necessaire en comparant les pointeurs : si ceux-ci sont égaux, la
copie peut être évitée.
Cette optimisation n'est valide _que_ si le compilateur peut déterminer
que
les effets de bord de la description sont bien réalisés. Évidemment, dans
le
cas où toute la mémoire est allouée directement ou indirectement par le
compilateur, il n'y a pas de problème : en fait, les compilateurs
optimisateurs peuvent même recréer l'effet global de l'opération
memmove(),
par exemple « peindre » l'objet, et aller jusqu'à supprimer l'appel à la
fonction s'ils déterminent que ce n'est pas utile... D'autres moins
subtils
vont quand même remplacer l'appel à memmove() par un appel à memcpy()
s'ils
« savent » (par exemple grâce à restrict) qu'il n'y a pas de
recouvrement...
D'autres encore vont manipuler les tables d'adressage virtuels pour
utiliser
les possibilités de C-O-W du matériel, en particulier si n est un multiple
de la taille de page, ou pour faire du débogage...
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi
facilement ce genre de raccourcis.
De ce fait, avec les discussions avec des ergoteurs dans mon genre qui
s'ensuivent (discussions qui commencent souvent par « avant cela marchait,
maintenant ça plante, remettez-moi ça comme c'était avant »...), et vu que
peu de programmes appelent memmove() avec s1==s2, il [me] paraît logique
que
les implémenteurs passe outre « l'optimisation » de tester explicitement
ce
cas.
D'après la description de la fonction, la mémoire doit bien être lue
et écrite, au moins dans la machine abstraite. Si l'implémentation
permet que les pointeurs void* adressent des dispositifs projetés en
mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser »
memmove() au point de ne pas faire de lecture.
Non, ta lecture de la norme est erronée :
Les mots importants dans cette specification sont "as if".
Dans le cas ou s1 == s2, une implementation qui ne copie rien a un
comportement indiscernable pour la machine obstraite d'une qui copie
les n bytes pointés par s2 vers une zone temporaire puis de cette
zone vers s1.
Le fait que la lecture ou l'ecriture aient effectivement lieu est
indétectable. Pour forcer un comportement précis de ce point de vue,
il faut qualifier les pointeurs comme "volatile" et détailler
l'algorithme.
Par definition, les effets de bord n'existent pas pour la machine
abstraite en l'absence du qualificatif volatile.
Par ailleurs, 'restrict' n'a pas le sens que tu sembles lui
attribuer, cf une discussion récente que j'ai initiée sur comp.std.c.
Tout ce que tu décris sont des optimisations specifiques pour des
architectures particulières où les developpeurs de la librairie C
pensent, souvent à juste titre, savoir précisément comment le
compilateur va traduire leur code et quel comportement cela va
permettre d'obtenir.
on ne doit pas s'en
inspirer outre mesure pour du code utilisateur,
et encore moins en conclure que la sémantique de la fonction soit plus
précise que ce que dit la norme.
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi facilement ce genre de raccourcis.
Bien sûr que si, et cela pose parfois des problèmes si le programmeur
un peu sorcier de la librairie ne s'y attendait pas. Le cas s'est
produit plusieurs fois, par exemple quand gcc a cessé de produire le
code de memset pour effacer les tableaux automatiques avant le retour
d'une certaine fonction de vérification de mot de passe.
D'après la description de la fonction, la mémoire doit bien être lue
et écrite, au moins dans la machine abstraite. Si l'implémentation
permet que les pointeurs void* adressent des dispositifs projetés en
mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser »
memmove() au point de ne pas faire de lecture.
Non, ta lecture de la norme est erronée :
Les mots importants dans cette specification sont "as if".
Dans le cas ou s1 == s2, une implementation qui ne copie rien a un
comportement indiscernable pour la machine obstraite d'une qui copie
les n bytes pointés par s2 vers une zone temporaire puis de cette
zone vers s1.
Le fait que la lecture ou l'ecriture aient effectivement lieu est
indétectable. Pour forcer un comportement précis de ce point de vue,
il faut qualifier les pointeurs comme "volatile" et détailler
l'algorithme.
Par definition, les effets de bord n'existent pas pour la machine
abstraite en l'absence du qualificatif volatile.
Par ailleurs, 'restrict' n'a pas le sens que tu sembles lui
attribuer, cf une discussion récente que j'ai initiée sur comp.std.c.
Tout ce que tu décris sont des optimisations specifiques pour des
architectures particulières où les developpeurs de la librairie C
pensent, souvent à juste titre, savoir précisément comment le
compilateur va traduire leur code et quel comportement cela va
permettre d'obtenir.
on ne doit pas s'en
inspirer outre mesure pour du code utilisateur,
et encore moins en conclure que la sémantique de la fonction soit plus
précise que ce que dit la norme.
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi facilement ce genre de raccourcis.
Bien sûr que si, et cela pose parfois des problèmes si le programmeur
un peu sorcier de la librairie ne s'y attendait pas. Le cas s'est
produit plusieurs fois, par exemple quand gcc a cessé de produire le
code de memset pour effacer les tableaux automatiques avant le retour
d'une certaine fonction de vérification de mot de passe.
D'après la description de la fonction, la mémoire doit bien être lue
et écrite, au moins dans la machine abstraite. Si l'implémentation
permet que les pointeurs void* adressent des dispositifs projetés en
mémoire (hypothèse
que j'ai faite ci-dessus, et qui doit être subséquement documentée en
conformité avec la clause 5), elle ne peut pas « optimiser »
memmove() au point de ne pas faire de lecture.
Non, ta lecture de la norme est erronée :
Les mots importants dans cette specification sont "as if".
Dans le cas ou s1 == s2, une implementation qui ne copie rien a un
comportement indiscernable pour la machine obstraite d'une qui copie
les n bytes pointés par s2 vers une zone temporaire puis de cette
zone vers s1.
Le fait que la lecture ou l'ecriture aient effectivement lieu est
indétectable. Pour forcer un comportement précis de ce point de vue,
il faut qualifier les pointeurs comme "volatile" et détailler
l'algorithme.
Par definition, les effets de bord n'existent pas pour la machine
abstraite en l'absence du qualificatif volatile.
Par ailleurs, 'restrict' n'a pas le sens que tu sembles lui
attribuer, cf une discussion récente que j'ai initiée sur comp.std.c.
Tout ce que tu décris sont des optimisations specifiques pour des
architectures particulières où les developpeurs de la librairie C
pensent, souvent à juste titre, savoir précisément comment le
compilateur va traduire leur code et quel comportement cela va
permettre d'obtenir.
on ne doit pas s'en
inspirer outre mesure pour du code utilisateur,
et encore moins en conclure que la sémantique de la fonction soit plus
précise que ce que dit la norme.
Mais dans le cas où le compilateur (ou l'implémenteur) n'a pas autant
d'information sur l'environnement cible, il ne peut plus se permettre
aussi facilement ce genre de raccourcis.
Bien sûr que si, et cela pose parfois des problèmes si le programmeur
un peu sorcier de la librairie ne s'y attendait pas. Le cas s'est
produit plusieurs fois, par exemple quand gcc a cessé de produire le
code de memset pour effacer les tableaux automatiques avant le retour
d'une certaine fonction de vérification de mot de passe.