C
Christian Bau
"Branimir Maksimovic said:In case that sizeof(x) == 1 , I agree.
Well, I don't need to, cause I don't use memcpy to assign variables.
In other words, you are a complete bullshitter.
"Branimir Maksimovic said:In case that sizeof(x) == 1 , I agree.
Well, I don't need to, cause I don't use memcpy to assign variables.
[snip explanation that second memcpy might be faster][snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
Greg said:Not necessarily. If one can show that Y performs every operation that
X performs, and then has to perform additional operations outside of
that set and that require a measurable amount of time to complete,
then one would have successfully proven that X is faster than Y.
Old said:Not true, unless the additional operations are independent of the
X operations.
For example, if you apply the same logic to a file system, then
appending data to a file should increase the amount of space
required to store a file. But for many filesystems that is not
true.
Similar possibilities apply to the CPU case. Maybe the extra
operation fits within some timing interval that had to happen
anyway. Maybe the extra instruction means the whole operation
can be done with different assembly instructions that work out
faster. Maybe the CPU's pipelining is better in one case than
the other. Etc.
peter said:Christian Bau skrev:
[snip explanation that second memcpy might be faster][snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
and is just utterly contrived and useless.
You
also have my sympathy when you call a poster who suggests using
assignment to assign for a "complete bullshitter".
peter said:Christian Bau skrev:
[snip explanation that second memcpy might be faster][snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
William said:peter said:Christian Bau skrev:
[snip explanation that second memcpy might be faster][snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
and is just utterly contrived and useless.
Contrived yes. Most simple examples of complex behaviour
are contrived. Useless no. Indeed this code is not meant
to be used but the *example* of an "bigger operaton"
(copying x bytes rather than x-1 bytes) that might reasonably
be expected to execute faster is useful indeed.
A related question. Is it ever better to use an int
variable, even when a char is big enough?
[For a less useful example consider a perverse
implementation (e.g. the DS2K) which introduces a
delay of say 20 minutes, seemingly at random. If the "smaller"
operation incurs the delay, but the "bigger" does not, then
the larger operation will be faster. While this
is correct, such an implementation cannot be considered
reasonable.]
You
also have my sympathy when you call a poster who suggests using
assignment to assign for a "complete bullshitter".
The poster claimed undefined behaviour, then when challenged
claimed ignorance (and gave a stupid exuse for this
ignorance). The term "complete bullshitter" seems an accurate
description.
Branimir said:double x[2];y=0.;
memcpy((char*)x+1,&y,sizeof(y));
double t = *(double*)((char*)x+1); /* depends on
hardware tolerance to alignment */
memcpy(x,&y,sizeof(y));
t = *x;
It is obvious that second case will be always faster or at least
equal then first case, even if memcpy have to copy same number of bytes
and use ram instead or sizeof (x) ==1 .
Jordan Abel said:peter said:Christian Bau skrev:
[snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
[snip explanation that second memcpy might be faster]
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
for example you could end up with a trap representation in x. say, a
signalling nan of some kind. and in any case you're not guaranteed
anything useful about the value you might get
No I didn't claim undefined behavior.
I claimed that first case would probably produce hardware exception
and second one would probably work.
The original message claimed
Jordan said:peter said:Christian Bau skrev:
[snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
[snip explanation that second memcpy might be faster]
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
for example you could end up with a trap representation in x. say, a signalling
nan of some kind.
and in any case you're not guaranteed anything useful about
the value you might get
Branimir said:William said:peter said:Christian Bau skrev:
[snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
[snip explanation that second memcpy might be faster]
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
and is just utterly contrived and useless.
Contrived yes. Most simple examples of complex behaviour
are contrived. Useless no. Indeed this code is not meant
to be used but the *example* of an "bigger operaton"
(copying x bytes rather than x-1 bytes) that might reasonably
be expected to execute faster is useful indeed.
A related question. Is it ever better to use an int
variable, even when a char is big enough?
[For a less useful example consider a perverse
implementation (e.g. the DS2K) which introduces a
delay of say 20 minutes, seemingly at random. If the "smaller"
operation incurs the delay, but the "bigger" does not, then
the larger operation will be faster. While this
is correct, such an implementation cannot be considered
reasonable.]
You
also have my sympathy when you call a poster who suggests using
assignment to assign for a "complete bullshitter".
The poster claimed undefined behaviour, then when challenged
claimed ignorance (and gave a stupid exuse for this
ignorance). The term "complete bullshitter" seems an accurate
description.
No I didn't claim undefined behavior.
I claimed that first case would probably produce hardware exception
William said:Branimir said:William said:peter koch wrote:
Christian Bau skrev:
[snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
[snip explanation that second memcpy might be faster]
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
and is just utterly contrived and useless.
Contrived yes. Most simple examples of complex behaviour
are contrived. Useless no. Indeed this code is not meant
to be used but the *example* of an "bigger operaton"
(copying x bytes rather than x-1 bytes) that might reasonably
be expected to execute faster is useful indeed.
A related question. Is it ever better to use an int
variable, even when a char is big enough?
[For a less useful example consider a perverse
implementation (e.g. the DS2K) which introduces a
delay of say 20 minutes, seemingly at random. If the "smaller"
operation incurs the delay, but the "bigger" does not, then
the larger operation will be faster. While this
is correct, such an implementation cannot be considered
reasonable.]
You
also have my sympathy when you call a poster who suggests using
assignment to assign for a "complete bullshitter".
The poster claimed undefined behaviour, then when challenged
claimed ignorance (and gave a stupid exuse for this
ignorance). The term "complete bullshitter" seems an accurate
description.
No I didn't claim undefined behavior.
I claimed that first case would probably produce hardware exception
And this differs from undefined behaviour how?
(are you claiming implementation defined behaviour?)
Anyway, you have yet to even attempt to justify your
claim that the first case would probably produce
a hardware exception.
"peter koch said:Christian Bau skrev:
[snip explanation that second memcpy might be faster][snip]
Not necessarily. If one can show that Y performs every operation that X
performs, and then has to perform additional operations outside of that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour and is just utterly contrived and useless. You
also have my sympathy when you call a poster who suggests using
assignment to assign for a "complete bullshitter".
In short, you have described yourself and your skills wonderfully in
two short posts.
Branimir said:In case that sizeof(x) == 1 , I agree.
Well, I don't need to, cause I don't use memcpy to assign variables.
Jordan Abel said:peter said:Christian Bau skrev:
[snip]
Not necessarily. If one can show that Y performs every operation that
X
performs, and then has to perform additional operations outside of
that
set and that require a measurable amount of time to complete, then one
would have successfully proven that X is faster than Y.
One would have proven no such thing.
Consider this:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
[snip explanation that second memcpy might be faster]
Hi Christian
Just a marvellous example you gave us - code that in C++ (and C) causes
undefined behaviour
What is the undefined behaviour (assume sizeof (x) >1)
for example you could end up with a trap representation in x. say, a
signalling
nan of some kind. and in any case you're not guaranteed anything useful about
the value you might get
"Branimir Maksimovic said:No I didn't claim undefined behavior.
I claimed that first case would probably produce hardware exception
and second one would probably work.
As memcpy is defined to be copy operation of n characters from
memory location to memory location, behavior is undefined only
when "to" and "from" overlap.
The original message claimed that compiler can be smart enough
to recognize use case and according to situation, apply different
semantics then those specified by code.
This leads him to conclusion that produced code will be faster when
compiler applies assignment semantics then memcpy semantics.
This is just wrong example, but if we observe this:
double x[2];y=0.;
memcpy((char*)x+1,&y,sizeof(y));
double t = *(double*)((char*)x+1); /* depends on
hardware tolerance to alignment */
memcpy(x,&y,sizeof(y));
t = *x;
It is obvious that second case will be always faster or at least
equal then first case, even if memcpy have to copy same number of bytes
and use ram instead or sizeof (x) ==1 .
Michael said:Which is nothing more than you did before.
Beside the point.
--- C99 ---
7.21.2.1 The memcpy function
Synopsis
1 #include <string.h>
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
Description
2 The memcpy function copies n characters from the object pointed to by
s2 into the object pointed to by s1. If copying takes place between
objects that overlap, the behavior is undefined.
Returns
3 The memcpy function returns the value of s1.
------------
The only way to safely and portably access the representation of an
object is bytewise (unsigned char). memcpy() does exactly that.
The first memcpy() operation can be replaced
size_t i;
unsigned char *p1= (unsigned char*) &y;
unsigned char *p2= (unsigned char*) &x;
for (i = 0; i < (sizeof x - 1); i++)
*(p2++) = *(p1++);
A conforming implementation has to do this right; you are thinking
of actual hardware and concluding that it cannot work.
Still, the "as if" rule has to hold, the operation has to work. There
must not be any repercussions as long as x is not accessed afterwards.
"Branimir Maksimovic said:If implementation is allowed to use floating point registers
for memcpy, then yes implementation defined behavior.
Question is: Are such implementations conformant?
eg:
double x,double y; // produces FPU exception if x,y gets trap value?
memcpy(&x,&y,sizeof(x)); // produces exception if FPU registers are
used
// and y has trap representation value
// which is non conformant as I understand memcpy semantics
Conclusion: if FPU registers are allowed to be used
for memcpy then it is normal to allow hardware exceptions
during memcpy.
Christian said:This is just wrong example, but if we observe this:
double x[2];y=0.;
memcpy((char*)x+1,&y,sizeof(y));
double t = *(double*)((char*)x+1); /* depends on
hardware tolerance to alignment */
I would recommend to write ((char *) x) + 1 instead of (char *) x + 1,
so that (1) everyone knows what the expression means without having to
look up the precedence of cast operators, and (2) everyone knows that
what you wrote is what you meant.
memcpy(x,&y,sizeof(y));
t = *x;
It is obvious that second case will be always faster or at least
equal then first case, even if memcpy have to copy same number of bytes
and use ram instead or sizeof (x) ==1 .
In this case, the first assignment to t will have undefined behavior.
There are implementations where it will crash, there are others where it
will be set t to the same value as y, just very slowly, but it is
undefined behavior.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.