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

I guess somebody downvoted you for the shortness of your comment. You probably know this, but repne movsb is actually a fairly slow approach to copying data compared to the various SSE assembly implementations that libc and friends have. The only thing repne movsb has going for it is how short its encoding is.

It is a bit bizarre that modern CPUs don't have an instruction for something as basic as "copy N bytes as fast as you can", and instead we're in a situation where library and compiler writers have to tune their assembly for different micro-architectures. (I'm not saying that it's a wrong decision, there are probably good reasons for doing things this way, but it's not something you'd expect.)



"rep movsb" (note: not "repne") actually is one of the fastest ways to copy memory on Ivybridge and Haswell (about as fast as vectorized copy implementations when the data is resident in L1/L2, and significantly faster than vector copy loops when the buffers are too large to be cache resident). On micro-architectures preceding Ivybridge, rep movsb is indeed slow.

It's still not quite "as fast as you can"; it's possible to beat rep movsb when buffers are small due to edging effects, but it's about as close as it's possible to come to that today.


On micro-architectures preceding Ivybridge, rep movsb is indeed slow.

Actually, rep movsb/movsw/movsd has been at the top at least since Nehalem (confirmed with benchmarks), and "fast string mode" which does cacheline-sized copies has been around since the P6; you may be able to squeeze out a few % more with SSE (or MMX), but the much larger code of the SSE-based copy functions (especially for alignment) is often not a win overall. Intel only really started advertising that they made it even faster with Ivybridge.

It was the fastest way to do memory copies on the 8086/8088, and might've been the fastest until around the time of the 486 and Pentium when it could be beaten by other techniques; but now it seems that it's coming back in favour.

There's an interesting discussion about this instruction on the Intel forums here: https://software.intel.com/en-us/forums/topic/275765


It was still nowhere near as fast as a good software sequence on Nehalem or Sandybridge. The startup cost to the microcode engine was simply too high, and its handling of misalignment was very inefficient. For "small" (< 1K) unaligned buffers (which are actually a large portion of memcpy usage on a live system), good software sequences were 3-4x faster than REP MOVS.

It did perform competitively for large all-aligned copies, which are what most people tend to look at when they post "memcpy benchmarks", but those turn out to be a relatively small portion of actual usage in most workloads.


Wow, thanks for pointing this out. I just tried it out for myself, and indeed "rep movsb" is consistently (and sometimes significantly) faster than the standard C memcpy for aligned copies larger than 16KB or so on my Intel Core i5 (for unaligned copies, it seems to be on par). It is slightly slower or on par for smaller sizes. There is no noticeable difference between rep movsb and repmovsq.

Apparently, libc hasn't caught up to those micro-architecture changes yet :/


Depends on whose libc you're using. Good implementations definitely take advantage of rep movsb where it's fast.


I guess the libc that comes with Ubuntu doesn't count as a good implementation.


glibc is generally pretty good, but does lag commercial libc implementations somewhat when it comes to microarchitectural optimization. It's also not unheard of for Linux distros to include rather old versions of glibc. I have no idea if that's the problem in your case, but it's worth checking that you have the latest.


> You probably know this, but repne movsb is actually a fairly slow approach to copying data compared to the various SSE assembly implementations that libc and friends have.

That used to be the case. As is mentioned, modern processors have fixed the 'rep' prefix to be much faster. Under linux, if your /proc/cpuinfo shows 'rep_good' in the flags section, then your CPU is of this newer class.


Just to be perfectly precise, not all uses of the rep prefix are fast now. Only rep movs and rep stos are improved, IIRC.


Yes I agree, what bothers me is that instead of that we are getting micro-code bloating instructions such as PEXT and PDEP.


Personally, I think those two are great. One of my tasks recently as accelerating VByte encoding, and PDEP/PEXT are practically made for the task. I don't think either of them is micro-coded. Both are 3-cycle latency, but use only a single Port 1 µop. I really like the BMI/BMI2 instructions sets, and find them to be of equal or greater immediate benefit than AVX2 (which I like too).


PDEP and PEXT are wonderful little instructions (and as you say, they are not micro-coded).




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

Search: