News for hackers. Stuff that matters.
Re:C performance mystery: delete unused string constant by userbinator on Wednesday June 24, 2020 @07:42PM (#23635148)
This is one of the reasons why I think microbenchmarks are either not very useful or completely misleading --- they'll favour things like insanely unrolled loops or aligned data with lots of padding, when in fact on a macro-scale those things will certainly affect performance negatively due to cache misses.

My preferred approach when optimising is to go for size first; then if more speed is desired, carefully apply size-increasing optimisations to areas which may benefit, testing with a macro benchmark to judge any improvement.

Re:C performance mystery: delete unused string constant by YZF on Wednesday June 24, 2020 @08:59PM (#23635669)
If the macro scale is dominated by the code you're optimizing, which is often the case, let's say some inner loops of a codec, signal processing, etc. then the cache misses that may follow aren't really a concern. Obviously(?) taking some random code that doesn't run frequently and trying to optimize it won't make a difference. Microbenchmarks are pretty useful in this context since they let you iterate faster. More generally the question is what is the bottleneck, if the bottleneck is fetching stuff into caches then that's what you optimize for, if the bottleneck is some computation that is running from caches then that's what you optimize...
Re:C performance mystery: delete unused string constant by jeffbee on Wednesday June 24, 2020 @09:27PM (#23635870)
The big cautionary tale of microbenchmarking is memcpy. If you look at the Gnu memcpy, it's ridiculously long and obviously been guided by extensive benchmarking. And memcpy often shows up in profiles, so it is a big target. But in real systems a small simple loop will perform better due to icache pressure.
Re:C performance mystery: delete unused string constant by makapuf on Thursday June 25, 2020 @03:10AM (#23637727)
Memcpy lights not be a good example however because it's often replaced by a loop (or a move or eliminated altogether) by the compiler, because it's such a commun function that its understood by the compiler, and the tradeoff of the real function are also understood and taken into account (of course I'm sure there are bad optimizations)
Re:C performance mystery: delete unused string constant by MaxBarraclough on Thursday June 25, 2020 @04:56AM (#23638410)
> in real systems a small simple loop will perform better due to icache pressure

Do you have a source for this? Seems surprising GCC would leave such low-hanging fruit. G++ makes the effort to reduce std::copy to a memmove call when it can, or at least some of the time when it can (or at least, it did so in 2011). [0]

Related to this: does GCC treat memcpy differently when it can determine at compile-time that it's just a small copy?

[0] https://stackoverflow.com/a/4707028/

Re:C performance mystery: delete unused string constant by Gibbon1 on Thursday June 25, 2020 @04:23PM (#23645237)
Problem is superscalar processors the correspondence between number of instructions and speed breaks down. Partly because the processor does it's own optimization on the fly and can do multiple things in parallel.

A programmer should be careful about second guessing the compiler. And a compiler should be careful about second guessing the processor.

Re:C performance mystery: delete unused string constant by MaxBarraclough on Friday June 26, 2020 @04:42AM (#23649967)
I'm not sure if you're implying this is premature optimisation. It isn't.

It's a performance-sensitive standard-library function, the kind of thing that deserves optimisation in assembly. It's also the kind of problem that can be accelerated with SIMD, but that necessarily means more complex code. That's why the standard library implementations aren't always dead simple.

Here's a pretty in-depth discussion [0]. They discuss CPU throttling, caches, and being memory-bound.

[0] https://news.ycombinator.com/item?id=18260154

Re:C performance mystery: delete unused string constant by jeffbee on Thursday June 25, 2020 @11:55AM (#23642095)
Only personal experience. If you look at the memcpy in llvm's libc, it was contributed by Googlers who share my experience and perspective.
Re:C performance mystery: delete unused string constant by api on Wednesday June 24, 2020 @09:52PM (#23636033)
It's amazing to me that every CPU doesn't have specialized memory copying instructions given how common an operation this is and how it can be a bottleneck. We have hundreds of vector instructions to optimize all kinds of special cases but little for this most general thing?
Re:C performance mystery: delete unused string constant by jeffbee on Wednesday June 24, 2020 @10:05PM (#23636107)
Intel has `rep movs` which is recommended for general use, you can beat it for sizes < 128B using a specialized loop. A very good memcpy for general purposes would just branch over the size to either a specialized small copy or `rep movs` for larger sizes.

The GCC version is just bananas. https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysde...

Compare the newer ERMS implementation: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86...

Re:C performance mystery: delete unused string constant by andrewf on Wednesday June 24, 2020 @11:42PM (#23636670)
What's weird is that if you git blame a bit, a lot of the elaborate stuff was contributed by Intel.
Re:C performance mystery: delete unused string constant by jeffbee on Wednesday June 24, 2020 @11:53PM (#23636734)
Intel is at least as guilty of chasing misleading benchmarks as anyone else in the history of our field.
Re:C performance mystery: delete unused string constant by saagarjha on Thursday June 25, 2020 @04:11AM (#23638097)
No AVX2-optimized version? I'm disappointed…

Edit: it's rolled into the erms version.

Re:C performance mystery: delete unused string constant by userbinator on Wednesday June 24, 2020 @10:04PM (#23636100)
x86 does, it's called REP MOVS, and it copies entire cachelines at a time (if the size of the copy lets it.) AFAIK it has done this since the P6 family (Pentium II), and has only gotten better over time. As a bonus, it is only 2 bytes long. I believe the Linux kernel uses it as its default memcpy()/memmove().

Here's some very interesting discussion about it: https://stackoverflow.com/questions/43343231/enhanced-rep-mo...

Re:C performance mystery: delete unused string constant by unscaled on Thursday June 25, 2020 @03:39AM (#23637889)
It's funny enough that the REP family of instructions has existed at least since the original 8086/8088. It's very much a relic of the CISC heritage of the x86 ISA, and it was probably meant to make writing assembly code easier and to save space - rather to improve performance.

I remember it was actually quite common in early PC programs, but I don't remember well enough whether it was also generated by compilers, or just existed in hand-optimized assembly (which was of course extremely common back then).

Re:C performance mystery: delete unused string constant by api on Wednesday June 24, 2020 @10:09PM (#23636142)
Why isn't it the default everywhere?
Re:C performance mystery: delete unused string constant by jeffbee on Wednesday June 24, 2020 @10:18PM (#23636203)
As I tried to indicate, the microbenchmark-guided unrolled loops look better than the simple `rep` instruction because the benchmarks aren't realistic. They don't suffer from mispredicted branches, they don't experience icache pressure. Basically the microarchitectural reality is absent in a small benchmark.

There's also the fact that `rep` startup cost was higher in the past than it is now. I think it started to get really fast around Ivy Bridge.

This is all discussed in Intel's optimization manual, by the way.

Re:C performance mystery: delete unused string constant by xelxebar on Wednesday June 24, 2020 @11:05PM (#23636475)
Neat. I was unaware of this manual. For the lazy but curious:

https://software.intel.com/content/www/us/en/develop/downloa...

And if you want ALL THE THINGS:

https://software.intel.com/content/www/us/en/develop/article...

Re:C performance mystery: delete unused string constant by yvdriess on Thursday June 25, 2020 @03:57AM (#23638017)
Yes, some compilers emit AVX move instructions on memcpy or compiler-generated moves (e.g. pass by value struct). (In addition to the rep move mentioned in the sibling posts)
Re:C performance mystery: delete unused string constant by ckennelly on Thursday June 25, 2020 @12:31AM (#23636929)
llvm-libc's memcpy is heavily sized optimized for this reason. A dedicated instruction that is fast for all cases, is ideal, though.
Re:C performance mystery: delete unused string constant by GuB-42 on Wednesday June 24, 2020 @11:16PM (#23636540)
> My preferred approach when optimising is to go for size first

Agreed, in my experience, more often than not, size is speed. Small memory usage mean less cache misses, smaller memcpys, more chance of having data fit a single word, etc...

Re:C performance mystery: delete unused string constant by scoutt on Thursday June 25, 2020 @03:51AM (#23637967)
Except when loops unrolls make things faster.
Re:C performance mystery: delete unused string constant by ants_a on Thursday June 25, 2020 @05:02AM (#23638457)
That only tends to be the case for tiny loops where loop iterator updates can be folded into addressing displacements and that frees up an execution port needed for something else.

If you don't know what you are doing unrolling is just as likely to hurt performance because you don't fit into uOP cache and get less decode bandwidth as a result. Or you increase ICache pressure on macro benchmarks and hurt real world performance. Modern cores are really good at hiding loop accounting overhead.

Re:C performance mystery: delete unused string constant by scoutt on Thursday June 25, 2020 @08:29AM (#23639876)
In a world where all the electronic devices are composed of x86 cores and/or have a data and/or instruction cache, it could be true.

But there are plenty of architectures out there where space-time tradeoffs (by optimized compilers) are still a thing (my PoV is from the embedded industry).

Re:C performance mystery: delete unused string constant by jhallenworld on Wednesday June 24, 2020 @09:41PM (#23635965)
I've found an interesting converse with macro benchmarks: small improvements to any of the top functions shown in your profiler output will have a relatively larger than expected effect on the overall speed. I mean you make a change that improves just one function by a little bit on its own (within the benchmark), but the overall is better than this. I think you end up freeing resources used by everything else.

The trick is to optimize the right macro benchmark- one that matches your customer's key use case I suppose.