3 ms·
According to Intel themselves[1], REP MOVS is optimal only for large copies, above about 2kb. Below that the large startup costs of the microcode sequence can b
by eloff 10y ago
According to Intel themselves[1], REP MOVS is optimal only for large copies, above about 2kb. Below that the large startup costs of the microcode sequence can be beaten by hand-written code for the target architecture. Which explains why glibc takes that approach. The linux kernel on the other hand, just goes with:
shrq $3, %rcx
andl $7, %edx
rep movsq
movl %edx, %ecx
rep movsb
Torvalds justified it as a way to force Intel and AMD to do the right thing and optimize the rep movs* instructions. He was annoyed at the code complexity of "more optimal" apporaches, and like you, concerned about icache effects.
A hand-written memmove is faster in microbenchmarks, but the icache effects may make the overall performance difference smaller (or even negative.) That's harder to measure.
AFAIK glibc does get better results than the kernel approach, but they've also introduced bugs[3] that way and the code is very complex by comparison. Also worth noting is that the kernel usually runs with a cold(er) icache, which is why they compile for size rather than speed (last I checked anyway, which was long ago) and why their memmove may make more sense in the context of the kernel. Also I suspect copies in the kernel are more likely to be larger (e.g. packets, pages, blocks) as opposed to small objects in userspace.
[1] http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html http://www.intel.com/content/www/us/en/architecture-and-tech...
[2] https://github.com/torvalds/linux/blob/master/arch/x86/lib/memcpy_64.S https://github.com/torvalds/linux/blob/master/arch/x86/lib/m...
[3] https://bugzilla.redhat.com/show_bug.cgi?id=638477#c99 https://bugzilla.redhat.com/show_bug.cgi?id=638477#c99