1
votes

I want know what the fastest function for copy n bytes from *source to *destination, when *destination = *source + k, and k is netural or zero.

The memcpy() function has undefind behavior for overlapping.

The memmove() function is not the best, since it has to check the overlapping side.

There is another function that is optimal to my case?

Thanks in advance!

2
Why is memmove "not the best"?user2864740
What does "k is neutral" mean?Michael Burr
You may be interested in the comment thread on this glibc bug report from a couple years ago about the merits of having memory copy functions that depend on the relative position of dest and src as a pre-condition for proper operation: sourceware.org/bugzilla/show_bug.cgi?id=12518 I'd suggest just using memmove() - what is a correct positioning of dest and src today becomes a different positioning in several months when the code is modified by someone unaware of the importance of what is nearly always a minor detail taken care of by the compiler, linker, or OS.Michael Burr
@user2864740 memmove has to correct position of the source and dest in order to prevent the overlapping problem. That's unnecessary in my case.user1134316
@MichaelBurr That's mean that I want to call the function like that: memcpy(*source + 2, *source, 3)user1134316

2 Answers

2
votes

memmove() has to spend some time determining how and whether the source and target overlap, so it can decide the order in which to copy the data.

Hypothetically, a version of memmove() that omits this initial calculation, either because it assumes a particular direction or because it has an extra parameter that lets you tell it, might be a little faster than memmove().

But there is no such function in the standard library.

You could write your own function, but it's unlikely that it would be as fast as your system's memmove(), which is very likely to be heavily optimized. You could grab a copy of the source code for your system's memmove() function (if it's available) and modify it, but the result would likely be non-portable (memmove() can depend on the characteristics of the system it's running on).

But it's very unlikely that it would be worth the effort. The time memmove() spends doing the initial calculation is, for moves of reasonable size, likely to be a small fraction of the time spent copying the data.

Unless you know from actual measurement that the initial computation performed by memmove() carries a significant performance penalty for your program, just use memmove() itself.

3
votes

memmove() is fine. It will figure out the direction of the move on its own by comparing the two pointers — an implementation might look something like:

void * memmove(void *dst, const void *src, size_t len)
{
    intptr_t dsti = dst;
    intptr_t srci = src;
    if (src > dst) {
        return _memmove_up(dst, src, len);
    } else {
        return _memmove_down(dst, src, len);
    }
 }

On most CPUs, this will compile to perhaps a half dozen extra instructions, which are only executed once when the function is called — there is no benefit to bypassing this.

(In theory, there is no reason why memcpy() should not be able to do a similar comparison itself to remove the distinction between it and memmove(). However, for some unfortunate historical reason, the authors of the C standard library did not decide to make this simplification, so we're stuck with these two functions.)