set double array to 0.0

F

Flash Gordon

But why am I overlapping my data copies?

One reason was given just below this question. What is wrong with the
given reason?
Well, I see where you are coming from now, but I find it hard to
believe an index array can be very time consuming on modren computers.

Why would you want to write a for loop and use indexing when you can
make a single library call?

Anyway, if a simple for loop is the most efficient method then the
library is likely to use that method.
I suppose if you had thousands of pointers, but then you would want a
linked-list, wouldn't you? And by then, you'd want an ISAM structure
or something.

When doing a text editor will you have a linked list of characters so
you can insert and delete characters? I think not. You might have a
linked list of blocks of of text, but you will still have to insert in
to and delete from the middle of a block, and the simple way to do that
is with memmove.
My point was, if it's small and known, you might be better off using a
for loop or two memcopy's, and if it's big enough then a memmove() is
inappropriate because you should be using something better.

Why write a loop or do a malloc/memcpy/memcpy/free (you can't use a
static buffer if the amount of data is variable) when a single memmove
will do the job correctly?
Either way the programmer should control what happens. However, I have
been mistaken before.

When you call memmove you ARE in control. It is well defined what will
happen and you call it because that is the right thing to do.
 
D

Dag Viken

Mabden said:
into

But why am I overlapping my data copies?


Well, I see where you are coming from now, but I find it hard to believe an
index array can be very time consuming on modren computers. I suppose if you
had thousands of pointers, but then you would want a linked-list, wouldn't
you? And by then, you'd want an ISAM structure or something.

My point was, if it's small and known, you might be better off using a for
loop or two memcopy's, and if it's big enough then a memmove() is
inappropriate because you should be using something better.

Either way the programmer should control what happens. However, I have been
mistaken before.

The functions memmove() and memcpy() both copy data from the source buffer
to the destination buffer; the difference is that only memmove() is
guaranteed to copy overlapping buffers correctly. To do so memmove() just
needs to determine if data should be copied from low addresses to high
addresses or from high to low addresses. The test for that is fairly simple
as shown in this generic (non-optimized) routine from VC runtime library
source:

void * memmove(void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers or Overlapping with dst <= src
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
/*
* Overlapping Buffers with dst > src
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;

while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}

The generic memcpy() routine is just a subset of memmove():

void * memcpy (void * dst, const void * src, size_t count )
{
void * ret = dst;
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}

The preceding functions should be portable but ineffective. Out of curiosity
I had a look at the optimized assembler source code in the VC runtime
library and surprise, surprise! memcpy() and memmove() are using the exact
same source code! This means that both functions perform memmove(). There is
no pure memcpy() available and frankly that is OK by me. memmove() must
handle overlap, and if memcpy() also does so, I do not think it conflicts
with the C standard, and the overhead is minimal. Of course this is system
dependent behavior.

My point is that memmove() can be used wherever memcpy() can be used but not
vice versa, unless the code relies on memcpy() behaving in a certain way.

Dag
 
B

boa

Dag said:
The functions memmove() and memcpy() both copy data from the source buffer
to the destination buffer; the difference is that only memmove() is
guaranteed to copy overlapping buffers correctly. To do so memmove() just
needs to determine if data should be copied from low addresses to high
addresses or from high to low addresses. The test for that is fairly simple
as shown in this generic (non-optimized) routine from VC runtime library
source:

void * memmove(void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers or Overlapping with dst <= src
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
/*
* Overlapping Buffers with dst > src
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;

while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}

The generic memcpy() routine is just a subset of memmove():

void * memcpy (void * dst, const void * src, size_t count )
{
void * ret = dst;
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}

The preceding functions should be portable but ineffective. Out of curiosity
I had a look at the optimized assembler source code in the VC runtime
library and surprise, surprise! memcpy() and memmove() are using the exact
same source code! This means that both functions perform memmove(). There is
no pure memcpy() available and frankly that is OK by me. memmove() must
handle overlap, and if memcpy() also does so, I do not think it conflicts
with the C standard, and the overhead is minimal. Of course this is system
dependent behavior.

My point is that memmove() can be used wherever memcpy() can be used but not
vice versa, unless the code relies on memcpy() behaving in a certain way.

<OT>
VC supports a pragma named intrinsic, which you can use to tell VC to
inline some commonly used functions. memcpy() is one of those functions,
memmove() is not(VC 6.0). This means that using memcpy() instead of
memmove() *may* result in a faster/smaller executable.
</OT>

boa@home
 
B

Ben Pfaff

Dag Viken said:
memmove() must handle overlap, and if memcpy() also does so, I
do not think it conflicts with the C standard, and the overhead
is minimal. Of course this is system dependent behavior.

My favorite behavior for this kind of thing is for memcpy() to
check whether the regions overlap and give a big fat warning at
runtime if so (but only if I compile in "debug mode"). It would
then be preferable for it to do the right thing (e.g. act like
memmove()).

Note that there is no efficient (O(1)) and portable way for
memcpy() to detect whether the regions passed in overlap.
 
C

Christian Bau

Keith Thompson said:
(In real life, memmove() is likely to check whether the source and
destination overlap, choosing an order that avoids problems. There's
no portable way to do that without invoking undefined behavior, but
the memmove() implementation is free to use non-portable tricks.)

There is a portable way, but it takes n pointer comparisons :-( (You'd
have to compare src, src+1, src+2 etc to dst and dst, dst+1, dst+2 etc.
to src).
 
C

Christian Bau

"Mabden said:
In any case, you are better off knowing your own data, and doing the
appropriate copying.

Has anyone done speed checks for mallocing a new chunk and copying the
correct data versus a memmove?

Who even does memmove? It sounds like sloppy programming to me. I mean does
the memory overlap or not?! If you don't know, why are you copying into it?

You use memmove for example to insert data into an array. For example,
if n elements of an array are used, and you want to insert an element at
index i, then you call

memmove (&a [i+1], &a , (n - i) * sizeof (a [0]));
 
B

Ben Pfaff

Mabden said:
Who even does memmove? It sounds like sloppy programming to me. I mean does
the memory overlap or not?! If you don't know, why are you copying into it?

I used memmove() a few days ago to implement scrolling in a
framebuffer. In that case, I knew that the memory overlapped,
which meant that memmove() was the appropriate function to use.
 
C

CBFalconer

Dag said:
.... snip ...

The functions memmove() and memcpy() both copy data from the
source buffer to the destination buffer; the difference is that
only memmove() is guaranteed to copy overlapping buffers
correctly. To do so memmove() just needs to determine if data
should be copied from low addresses to high addresses or from
high to low addresses. The test for that is fairly simple as
shown in this generic (non-optimized) routine from VC runtime
library source:

void * memmove(void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers or Overlapping with dst <= src
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
/*
* Overlapping Buffers with dst > src
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;

while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}

The code you show is intrinsically invalid. You cannot compare
void * pointers for anything but equality. The initial portion
could read (but is still wrong):

void *memmove(void * dest, const void * sorc, size_t count)
{
unsigned char *dst = dest;
unsigned char *src = sorc;

after which you have no need for the 'ret' variable. Having done
the above you have a chance if the system has a flat memory, but
that is not guaranteed (you cannot compare pointers for other than
equality unless they are pointers within the same object). So the
whole setup process becomes system dependant, and is why this
function is supplied by the system. The implementors know how to
detect overlap safely in their system.

Moral: Use the system provided routines.
 
K

Keith Thompson

CBFalconer said:
The code you show is intrinsically invalid. You cannot compare
void * pointers for anything but equality.

Actually, I believe you can. For example, I believe the following
program:

#include <stdio.h>

int main(void)
{
char arr[100];
void *p0 = arr;
void *p1 = arr + 1;

if (p0 < p1) {
printf("ok\n");
}
else {
printf("Oops!\n");
}
return 0;
}

is portable and should print "ok".

That still leaves the problem of comparing pointers to different
objects, which of course can't be done portably (unless you're foolish
enough to do N equality comparisons).

But a particular implementation of memmove() is free to take advantage
of whatever system-specific tricks it can get away with, including
applying relational operators to pointers to different objects.
 
T

Tim Prince

Thomas Matthews said:
Tom said:
Carson wrote:

Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)


Um try something along these lines

double myarray[SIZE], tmp;

tmp = 0.0;
memcpy(myarray, &tmp, sizeof(double));
memcpy(myarray+1, &tmp, sizeof(double));
memcpy(myarray+2, myarray, sizeof(double)*2);
memcpy(myarray+4, myarray, sizeof(double)*4);
memcpy(myarray+8, myarray, sizeof(double)*8);
memcpy(myarray+16, myarray, sizeof(double)*16);
... until you cover SIZE

Tom

I believe that a simple "for" loop would be much
easier to understand and probably more efficient
{since the function call overhead is removed).

unsigned int i;
for (i = 0; i < SIZE; ++i)
{
myarray = 0.0;
}

As this NG is about C, not about specific implementations, this has to be
the best answer. If your compiler chooses to translate that into memset(),
knowing your target machine, fine. Your compiler may choose to translate
into parallel store instructions, should those be appropriate.
 
D

Dag Viken

CBFalconer said:
The code you show is intrinsically invalid. You cannot compare
void * pointers for anything but equality. The initial portion
could read (but is still wrong):

void *memmove(void * dest, const void * sorc, size_t count)
{
unsigned char *dst = dest;
unsigned char *src = sorc;

after which you have no need for the 'ret' variable. Having done
the above you have a chance if the system has a flat memory, but
that is not guaranteed (you cannot compare pointers for other than
equality unless they are pointers within the same object). So the
whole setup process becomes system dependant, and is why this
function is supplied by the system. The implementors know how to
detect overlap safely in their system.

Moral: Use the system provided routines.

Why not compare void* pointers? Is that in the C Standard? And what do you
mean by 'object' in the expression 'pointers within the same object'? Are
you thinking of segmented architectures? If so, yes, I assume a flat memory
model so in that sense the code is system dependant. Without flat memory I
think memcpy() would be faster than memmove(). Another assumption is that
memory is byte-addressable.

Note that the code was just meant as an example of how easily
memmove()/memcpy() could be implemented (assuming byte-addressable flat
memory). The code was found in the library source code provided with MS VC7.
The actual MS runtime library is using optimized assembler code, basically
doing the same as the example code, but employing optimizations such as
memory aligned copying and loop unrolling.

Finally, yes I do use the system routines.

Dag
 
B

Barry Schwarz

Why not compare void* pointers? Is that in the C Standard?

Yes. Other than == and !=, you cannot compare two pointers unless
they both point within the same object. Since void pointers do not
point to any object, they cannot meet the condition.
And what do you
mean by 'object' in the expression 'pointers within the same object'? Are

If you have an array and the pointers point to elements or one byte
past the last element, then the pointers are pointing within the same
object. If you have a scalar object, such as an int, it can be
considered as an array of 1 element for the above discussion. If you
have a struct with the pointers pointing to members of the struct or
one byte beyond the end of the struct, then these pointers also point
within the same object. The obvious extension applies to arrays of
struct.
you thinking of segmented architectures? If so, yes, I assume a flat memory
model so in that sense the code is system dependant. Without flat memory I

The C standard does not discuss memory models.
think memcpy() would be faster than memmove(). Another assumption is that

I think so also but the standard does not address this issue and it is
possible for a library to have a very good implementation for memmove
and a very poor one for memcpy.
memory is byte-addressable.

In C, memory is always byte addressable because sizeof(char) is always
1, regardless of how many bits a char contains.



<<Remove the del for email>>
 
K

Keith Thompson

Barry Schwarz said:
On Wed, 18 Aug 2004 09:10:23 GMT, "Dag Viken"


Yes. Other than == and !=, you cannot compare two pointers unless
they both point within the same object. Since void pointers do not
point to any object, they cannot meet the condition.

That's not quite right. void pointers can point to objects, and you
can do "<", ">", "<=", and ">=" comparions on two void pointers as
long as they both point to or within the same object (or just past the
end). C99 6.5.8, "Relational operators" specifically talks about
pointers to incomplete types (void is an incomplete type).

For example, after

void *ptr = malloc(42);

ptr points to an object (which doesn't happen to have an inherent
type).

But for purposes of implementing memmove(), you can't safely compare
the s1 and s2 arguments (other than for equality or inequality)
because you have no way of knowing whether they point into the same
object.
 

Ask a Question

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.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,831
Members
47,374
Latest member
anuragag27

Latest Threads

Top