 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Marc Boyer Guest
|
Posted: Tue Nov 16, 2004 2:28 pm Post subject: Re: c quoi le plus rapide ... |
|
|
In article <419a0d8e$0$18771$8fcfb975 (AT) news (DOT) wanadoo.fr>, dark poulpo wrote:
| Quote: | bonjour,
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
|
A priori
*( (int*) gauche->data )= r;
car le compilateur sait combien de char il doit copier,
et utiliser éventuellement l'instruction qui va bien
du processeur.
Alors que
memcpy
doit dynamiquement gérer sizeof(int) et peut-être même
faire un appel de fonction.
Ceci dit, si quelqu'un me dit que sur sa platerforme,
c'est le contraire, je serais pas étonné.
Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Tue Nov 16, 2004 2:39 pm Post subject: Re: c quoi le plus rapide ... |
|
|
"dark poulpo" <ggggggg@g.gg> writes:
| Quote: | bonjour,
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
|
Si ca a de l'importance, mesure, sinon fait le plus clair:
*static_cast<int*>(gauche->data) = r;
qui a priori sera plus rapide. Ca ne m'etonnerait pas que certains
compilateurs fassent la meme chose pour les deux -- memcpy est
standard et sizeof(int) est connu -- , mais ca m'etonnerait qu'il y en
ait qui gerent mieux memcpy que l'assignation -- par exemple sur des
machines avec des contraintes d'alignement fortes pour les int, la
premiere version permet de supposer que gauche->data est correctement
aligne, pas la deuxieme.
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
|
|
| Back to top |
|
 |
dark poulpo Guest
|
Posted: Tue Nov 16, 2004 2:41 pm Post subject: c quoi le plus rapide ... |
|
|
bonjour,
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
merci d'avance
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Wed Nov 17, 2004 9:29 am Post subject: Re: c quoi le plus rapide ... |
|
|
"dark poulpo" <ggggggg@g.gg> wrote
| Quote: | d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
|
Qu'importe, puisqu'il ne font pas la même chose. Si la sémantique du
programme exige le premier, le séconde ne marche pas, et vice versa. (En
général, le deuxième a un comportement indéfini, si data est un void*.)
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
|
| Back to top |
|
 |
PurL Guest
|
Posted: Wed Nov 17, 2004 1:14 pm Post subject: Re: c quoi le plus rapide ... |
|
|
| Quote: | int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
Qu'importe, puisqu'il ne font pas la même chose.
|
Soit plus précis ! l'autre exemple fait quoi s'il ne place pas la valeur de
r à l'adresse gauche->data ?
PurL
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Wed Nov 17, 2004 1:30 pm Post subject: Re: c quoi le plus rapide ... |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | "dark poulpo" <ggggggg@g.gg> wrote in message
news:<419a0d8e$0$18771$8fcfb975 (AT) news (DOT) wanadoo.fr>...
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
Qu'importe, puisqu'il ne font pas la même chose. Si la sémantique du
programme exige le premier, le séconde ne marche pas, et vice versa. (En
général, le deuxième a un comportement indéfini, si data est un void*.)
|
Je ne crois pas que le deuxieme soit un UB si tu penses aux problemes
d'alignement.
int r1, r2;
r1=10;
memcpy(gauche->data,&r1,sizeof(int));
r1=0;
memcpy(&r2,gauche->data,sizeof(int));
meme si gauche->data n'est pas aligne pour recevoir un int (je suppose
par contre qu'il y a la place de mettre un int), il n'y a pas de UB.
memcpy considere les src et dst comme des array de unsigned char. Tant
que cet array n'est pas interprete comme contenant un int, il ne devrait
pas y avoir de UB.
a+, ld.
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Nov 18, 2004 8:38 am Post subject: Re: c quoi le plus rapide ... |
|
|
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
"dark poulpo" <ggggggg@g.gg> wrote in message
news:<419a0d8e$0$18771$8fcfb975 (AT) news (DOT) wanadoo.fr>...
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
Qu'importe, puisqu'il ne font pas la même chose. Si la sémantique du
programme exige le premier, le séconde ne marche pas, et vice
versa. (En général, le deuxième a un comportement indéfini, si data
est un void*.)
Je ne crois pas que le deuxieme soit un UB si tu penses aux problemes
d'alignement.
|
Non. J'avais mal lu l'orginal, et je croyais que c'était le pointeur
qu'on copiait. Copier un void* dans un int*, et puis espérer accéder à
un int, a un comportement indéfini. Dans la mésure que les deux zones
mémoire ont le même type, et qu'il s'agit des POD, en revanche, le
memcpy doit marcher. (En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Thu Nov 18, 2004 10:27 am Post subject: Re: c quoi le plus rapide ... |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
|
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
a+, ld.
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Nov 18, 2004 10:44 am Post subject: Re: c quoi le plus rapide ... |
|
|
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
|
Ce qui est copie peut ne pas etre un int acceptable par
l'architecture.
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
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Thu Nov 18, 2004 12:47 pm Post subject: Re: c quoi le plus rapide ... |
|
|
Jean-Marc Bourguet wrote:
| Quote: | Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
Ce qui est copie peut ne pas etre un int acceptable par
l'architecture.
|
lequel? ou-t-il question d'un int, je ne vois que des sizeof(int) et des
void*?
a+, ld.
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Thu Nov 18, 2004 12:49 pm Post subject: Re: c quoi le plus rapide ... |
|
|
Laurent Deniau wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
|
Lire char buf. Je ne sais pas pourquoi j'ai mis unsigned (bien que dans
la pratique il n'y ait pas de difference pour ce qui suit).
| Quote: | int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
|
Mais en regardant 6.5-6 (effective type), j'ai un doute...
If a value is copied into an object having no declared type using
memcpy or memmove, or is copied as an array of character type, then the
effective type of the modified object for that access and for subsequent
accesses that do not modify the value is the effective type of the
*object from which the value is copied*, if it has one.
Est-ce que par hasard cela voudrait dire que memcpy et memmove seraient
en droit d'optimiser la copie en fonction de l'alignement (et de la
taille) de la src independament de la dst et donc que la dst doit
repondre au meme contraintes d'alignement que la src? J'ai du mal a le
croire car si la src vient d'un malloc, on aurait un UB sur la pluspart
des dst qui ne viennent pas aussi d'un malloc.
a+, ld.
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Nov 19, 2004 7:59 am Post subject: Re: c quoi le plus rapide ... |
|
|
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
|
Pas de problème. Je pensais à des choses du genre :
double d ;
int i ;
memcpy( &d, &i, sizeof( int ) ) ;
// ou
i = *(int*)( &d ) ;
Qu'on utilise memcpy ou la conversion, on a un comportement indéfini.
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Nov 19, 2004 8:17 am Post subject: Re: c quoi le plus rapide ... |
|
|
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote
| Quote: | Laurent Deniau wrote:
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
Lire char buf. Je ne sais pas pourquoi j'ai mis unsigned (bien que
dans la pratique il n'y ait pas de difference pour ce qui suit).
|
Moi aussi, j'utilise systèmatiquement unsigned char pour la mémoire
brute. En fait, je crois qu'en C++, char va aussi, mais qu'en C(90),
non, mais je suis loin d'en être sûr. Mais unsigned char marche dans
tous les cas, garanti, et au moins dans les milieux où j'ai travaillé,
c'est le type « standard » pour ce genre de chose. (En général, char
tout seul ne sert que pour des caractères.)
| Quote: | int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
Mais en regardant 6.5-6 (effective type), j'ai un doute...
[de la norme C99]
If a value is copied into an object having no declared type using
memcpy or memmove, or is copied as an array of character type, then
the effective type of the modified object for that access and for
subsequent accesses that do not modify the value is the effective type
of the *object from which the value is copied*, if it has one.
|
En voilà du standardais. J'avoue que je n'y comprends que dalle. Or que
mon anglais n'est pas si mauvais que ça. (Pour commencer, je ne sais pas
ce qu'ils entendent par « no declared type ». Toutes les expressions en
C ou en C++ ont un type.)
| Quote: | Est-ce que par hasard cela voudrait dire que memcpy et memmove
seraient en droit d'optimiser la copie en fonction de l'alignement (et
de la taille) de la src independament de la dst et donc que la dst
doit repondre au meme contraintes d'alignement que la src? J'ai du mal
a le croire car si la src vient d'un malloc, on aurait un UB sur la
pluspart des dst qui ne viennent pas aussi d'un malloc.
|
Je ne suis pas sûr, mais je crois que ce qu'il sont en train de dire
(voir le paragraphe suivant), c'est que si tu copies un int (disons)
dans un char[], le char[] contient un int -- tu peux la copier autant
que tu veux en tant que char[], mais si tu essaies à accéder à un des
copies en tant qu'autre chose que int ou char[] (ou un type compatible
avec un de ces deux), c'est un comportement indéfini.
Si c'est ça, c'est un peu ce que je disais dans mon autre réponse. Si tu
fais :
float f ;
int i ;
memcpy( &i, &f, sizeof( int ) ) ;
le type « effectif » de l'objet à l'adresse &f est un int, et si tu
essaies d'y accéder autrement que comme int ou comme char[], tu as un
comportement indéfini. (Et évidemment, toute utilisation de f va y
accéder en tant que float -- donc, comportement indéfini.) En revanche,
en supposant que des float soit assez grands, quelque chose comme :
float f ;
unsigned char* buf = (unsigned char*)&f
int i ;
memcpy( buf, &i, sizeof( int ) ) ;
memcpy( &i, buf, sizeof( int ) ) ;
est garanti. Je peux copier un int dans un float, tant que je n'accède
pas au float. (Mais je suis loins d'être sûr. Comme j'ai dit, j'ai
beaucoup de mal à comprendre ce paragraphe.)
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Fri Nov 19, 2004 10:56 am Post subject: Re: c quoi le plus rapide ... |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
news:<cni5v6$d7p$2 (AT) sunnews (DOT) cern.ch>...
Laurent Deniau wrote:
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> wrote in message
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
(En ce qui concerne l'alignement, si le void* n'a
pas été initialisé avec un int* avant, les deux versions ont un
comportement indéfini.)
C'est la que je ne te suis pas. Est ce que:
{
unsigned char buf[sizeof(int)]; // buf pas aligne sur un int*
Lire char buf. Je ne sais pas pourquoi j'ai mis unsigned (bien que
dans la pratique il n'y ait pas de difference pour ce qui suit).
Moi aussi, j'utilise systèmatiquement unsigned char pour la mémoire
brute. En fait, je crois qu'en C++, char va aussi, mais qu'en C(90),
non, mais je suis loin d'en être sûr. Mais unsigned char marche dans
tous les cas, garanti, et au moins dans les milieux où j'ai travaillé,
c'est le type « standard » pour ce genre de chose. (En général, char
tout seul ne sert que pour des caractères.)
int v1, v2;
v1=10;
memcpy(buf,&v1,sizeof(int));
memcpy(&v2,buf,sizeof(int));
// equivalent de v2 = v1
}
a un UB? Je ne crois pas.
Mais en regardant 6.5-6 (effective type), j'ai un doute...
[de la norme C99]
If a value is copied into an object having no declared type using
memcpy or memmove, or is copied as an array of character type, then
the effective type of the modified object for that access and for
subsequent accesses that do not modify the value is the effective type
of the *object from which the value is copied*, if it has one.
En voilà du standardais. J'avoue que je n'y comprends que dalle. Or que
mon anglais n'est pas si mauvais que ça. (Pour commencer, je ne sais pas
ce qu'ils entendent par « no declared type ». Toutes les expressions en
C ou en C++ ont un type.)
|
sauf le retour de malloc (si != NULL ). Il n'a pas de "declared type"
et il est aligne avec tous les types. Ce qui veut dire que l'objet
retourne n'aura aucun probleme de reinterpretation (a la C++ ) avec
un type declare (pas de UB).
Je suppose que derriere "effective type", ils mettent declared-type +
retour de malloc, ce qui inclu tous les cas pratiques d'alignement.
| Quote: | Est-ce que par hasard cela voudrait dire que memcpy et memmove
seraient en droit d'optimiser la copie en fonction de l'alignement (et
de la taille) de la src independament de la dst et donc que la dst
doit repondre au meme contraintes d'alignement que la src? J'ai du mal
a le croire car si la src vient d'un malloc, on aurait un UB sur la
pluspart des dst qui ne viennent pas aussi d'un malloc.
Je ne suis pas sûr, mais je crois que ce qu'il sont en train de dire
(voir le paragraphe suivant), c'est que si tu copies un int (disons)
dans un char[], le char[] contient un int -- tu peux la copier autant
que tu veux en tant que char[], mais si tu essaies à accéder à un des
copies en tant qu'autre chose que int ou char[] (ou un type compatible
avec un de ces deux), c'est un comportement indéfini.
|
Je pense qu'ils sont meme plus precis que ca: si tu essaye en tant que
int sur la dst, tu aura un UB, a cause de l'alignement de char[] qui
n'est pas aligne. Je pense qu'il essaye de dire que dans les cas
d'utilisation sous forme de char[], l'alignement n'a plus d'importance
*tant qu'on* n'utilise qu'un type char[] pour l'interpretation de la
valeur (memcpy, memmove). Donc les copies aller-retour dans un buffer ne
pause pas de probleme. Mais toute interpretation autre que char[] de la
valeur (meme apres le copier-coller) necessite de repecter les regles
des "declared types".
| Quote: | Si c'est ça, c'est un peu ce que je disais dans mon autre réponse. Si tu
fais :
float f ;
int i ;
memcpy( &i, &f, sizeof( int ) ) ;
|
vu ce qui tu dis apres je suppose que tu voulais ecrire
memcpy( &f, &i, sizeof( int ) ) ;
| Quote: | le type « effectif » de l'objet à l'adresse &f est un int, et si tu
essaies d'y accéder autrement que comme int ou comme char[], tu as un
comportement indéfini. (Et évidemment, toute utilisation de f va y
accéder en tant que float -- donc, comportement indéfini.) En revanche,
en supposant que des float soit assez grands, quelque chose comme :
float f ;
unsigned char* buf = (unsigned char*)&f
int i ;
memcpy( buf, &i, sizeof( int ) ) ;
memcpy( &i, buf, sizeof( int ) ) ;
est garanti. Je peux copier un int dans un float, tant que je n'accède
pas au float.
|
Ok, on est d'accord. Et c'est tant mieux parce que sinon memcpy est a
mettre a la poubelle .
| Quote: | (Mais je suis loins d'être sûr. Comme j'ai dit, j'ai
beaucoup de mal à comprendre ce paragraphe.)
|
a+, ld.
|
|
| Back to top |
|
 |
dark poulpo Guest
|
Posted: Fri Nov 19, 2004 4:34 pm Post subject: Re: c quoi le plus rapide ... |
|
|
"dark poulpo" <ggggggg@g.gg> a écrit dans le message de
news:419a0d8e$0$18771$8fcfb975 (AT) news (DOT) wanadoo.fr...
| Quote: | bonjour,
d'apres vous, c'est quoi le plus rapide entre
int *g =(int *)gauche->data; // data est void *
(*g) = r;
ET
memcpy(gauche->data,&r,sizeof(int));
|
pour info sur certain cas proposé,
il se trouve que gauche->data "dans ce cas la", est initialisé par un new
char[sizeof(int)];
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|