Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Linus had some strong opinions on the distinction between memcpy and memmove when it became a significant userspace issue on Linux a few years ago:

https://bugzilla.redhat.com/show_bug.cgi?id=638477#c132

I think he's probably right that there's no reason not to alias memcpy to memmove and make the latter smart enough to do the fastest possible thing given its input. Every implementation of memcpy and memmove that I've seen has been sufficiently complicated in order to optimize for big copies that an added comparison or two for bounds checking would seem a drop in the bucket.

But I'm open to practical examples where the performance difference would become significant.



One of the commits asserts memcpy triggers extra optimisations by hinting the areas are non-overlapping: http://marc.info/?l=openbsd-cvs&m=137026274514948&w=2

> Replace "hot" bcopy() calls in ether_output() with memcpy(). This tells the compiler that source and destination are not overlapping, allowing for more aggressive optimization, leading to a significant performance improvement on busy firewalls.


Aliasing optimisations will fire regardless of how memcpy/memmove are implemented.


Replying for masklinn, perhaps what they had in mind was the discovery of optimizations that are not allowed by strict aliasing rules. Consider:

    int *p, *q, x;
    ...
    memmove(p, q, 50 * sizeof(int));
    p[2] = 3;
    q[3] = 4;
    x = p[2];
In the example above, it is illegal (with only the information available) to optimize the last assignment to x = 3. Strict aliasing does not apply because everything is int.

If the call to memmove were a call to memcpy instead, a sufficiently creative compiler author could argue that the optimization of the last statement to x = 3 is legal, because the call to memcpy asserts (among other things) that the int pointed by p+2 does not have any bit in common with the int pointed by q+3.

I don't know how often that would trigger or how useful that would be. But I work on a system in which C programs can be annotated with properties (including non-aliasing properties: see http://blog.frama-c.com/index.php?post/2012/07/25/On-the-red... and http://blog.frama-c.com/index.php?post/2012/07/25/The-restri... ), and that makes me pretty confident that this would be sound and, unlike a joke I made two years ago about the redundancy of restrict in C99, workable.


That's exactly the kind of optimisation that I had in mind. What I'm saying is that the static analysis would work the same even if memcpy was implemented by jumping to memmove or some linker trick to make it resolve to memmove.


The issue that caused Linus to argue memcpy should just act like memmove involved old binaries breaking with new kernels, so the compiler's behaviour wasn't an issue there.


It was a bit more than that. He implied that the performance differences were trivial, so it wasn't worth the trouble.

I think, unfortunately, Linus' argument amounts to demanding that API's conform to how they are used rather than how they are specified, which leads to O_PONIES type problems.


It was a change in libc, not the kernel. Someone ran valgrind and found the binary-only flash plugin was depending on the undefined memcpy behaviour.

Linus was butting in because a kernel sound driver regression was also suspected earlier...


Perhaps in debug builds, memcpy could wrap memmove but assert() that the regions are non-overlapping? Would avoid code unintentionally relying on memcpy supporting overlap.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: