3 ms·
Copying blocks of memory is so common. Why isn't there a specific instruction for that in cpu architectures?
by rowanG077 6y ago
Copying blocks of memory is so common. Why isn't there a specific instruction for that in cpu architectures?
- vhold 6y agoI can't exactly answer that question because I'm not even sure if the premise is true, but I do know that "memory to memory" copying is often offloaded entirely off the CPU. Here's a technical overview of some of the technologies from 2017 https://www2.eecs.berkeley.edu/Pubs/TechRpts/2017/EECS-2017-2.pdf https://www2.eecs.berkeley.edu/Pubs/TechRpts/2017/EECS-2017-...
- jchw 6y agoThere are, kind of. For example x86 traditionally has `rep movsb`. However that doesn’t mean it will remain the fastest way to do things in the long term; AVX/SSE lets you copy more at once with the caveat that it is more complicated to use (due to alignment requirements and register usage.) (I think certain ‘obvious’ patterns are optimized in microcode, but it’s probably hard to beat moving 32 bytes or 64 bytes at once with moving bytes/words at a time, no matter what the processor does.)
- JoshTriplett 6y ago> For example x86 traditionally has `rep movsb`. However that doesn’t mean it will remain the fastest way to do things in the long term Starting with Ice Lake, you can just use `rep movsb` all the time, and the processor will move memory in the fastest way it can. The CPUID feature "ERMS", "Enhanced REP MOVSB", means you should use `rep movsb` for any memory copy that's at least 128 bytes. The CPUID feature "FSRM", "Fast Short REP MOVSB", implies ERMS and additionally means that you should use `rep movsb` for any memory copy, even if it's shorter than 128 bytes.
- twoodfin 6y agoNeat! Have any of the common libc’s picked this up yet? How does ERMS deal with interrupts? If I `rep movsb` while interrupted, do I also get the fast implementation?
- temac 6y agoMaybe while resuming from interrupt you go slow for a while, although I suspect you eventually recover even if that happen. The interrupt will be slow as hell anyway, regardless of if you are doing rep movsb or not. Actually rep movsb with ERMS better has to work well in presence of exceptions (to support virtual memory well), so as what happens in the core in case of interrupt is very similar to what happens on exceptions, I think it's fine to use ERMS even on a system that is heavily interrupted. Or maybe you ask what happens in an interrupt handler? Probably the same thing as everywhere else, I don't see why it would be different. The state of the interrupted code has been flushed back to architectural at this point, so you can and do regular microarchitectural optims (it would even be difficult not too, there is not often a slow path and then optims on top of that, it's more the whole implementation that is made using optimisation tricks everywhere)
- JoshTriplett 6y ago> Neat! Have any of the common libc’s picked this up yet? glibc has, as has the Linux kernel. > How does ERMS deal with interrupts? If I `rep movsb` while interrupted, do I also get the fast implementation? Whether or not you have ERMS/FSRM available, interrupts are always defined to occur at an architecturally defined state. I don't know of any reason why, when it resumes, it would stop being optimized.
- temac 6y agorep movsb has been quite optimized recently and I suspect it will continue to be. Today you can be faster with more complex solutions in some cases, and depending on your precise microarch alternate solution for small copies, etc., but I suspect eventually rep movsb will just be good enough for everything but the most demanding memcpy, which I'm not even sure has a good definition because in an ever increasing number of cases it will depend on what the other cores are doing... Intel seems to be improving rep movsb from gen to gen, and on the AMD side it seems Zen3 is getting ERMS and FRMS. Given how useful it is when you can't do AVX or just because it is insanely compact, I think its usage will only increase in the near/medium future. Long term, who knows, but like anything.
- oso2k 6y agoThere's actually dozens and dozens of such instructions on x86 and x86-64. So the question shouldn't really be if there is an instruction, it's whether the one you're using is the most performant for your given CPU. Old Linux kernels would actually calculate CPU speed, and whether 16-bit, 32-bit, FPU, MMX memory copies were fastest and pick one for the kernel to use.
- tjansen 6y agoI always wondered that myself, but 'rep movsb' sounds like a great solution. Back when I was still programming assembly, there were blitters (https://en.wikipedia.org/wiki/Blitter https://en.wikipedia.org/wiki/Blitter) to copy large chunks of memory.