4 ms·
No one tries to get the compiler to inline code? What? Doing a function call is quite expensive! If you're not worried about that level of performance why are
by xxpor 5y ago
No one tries to get the compiler to inline code? What?
Doing a function call is quite expensive! If you're not worried about that level of performance why are you using C these days in the first place?
- jeffbee 5y agoThe only legitimate way to influence the compiler's inlining decisions is by profile guidance. If you aren't providing a profile at compile time, you demonstrably do not care about performance.
- google234123 5y agoWhat a lazy generalization. Shame!
- 1ris 5y agoBut it's mostly true. Trust the compiler. They are very, very good. They have a better understanding of the performance characteristics of the current platform with the current code than the programmer. Another benefit is you do not need to maintain and update the manual optimisations once one assumption has changed. __force_inline does more bad than good. (some compilers these days have whole programm optimisation and outlining, things that make the decision when to inline and when not to inline even harder for humans)
- account42 5y agoI agree that in an ideal world function boundaries would be primarily for readability and at most a minor hint to compilers. But I also think youthat give compilers way too much credit. Compilers are still generally applying one relatively simple rule after another. Often that will get good results, but it sometimes fails in surprising ways because the compiler will not be able to predict the effect of one optimization on later ones. This is where hints such as "always inline" are useful, and that doesn't even have to do anything with the target platform. And as for PGO, yes that's useful, but it's also not a silver bullet: a) mentioned above, thresholds for local optimizations (which is what PGO affects) are not always enough and b) getting a representative profile is not trivial and also needs to be kept up to date.
- MauranKilom 5y ago> Trust the compiler. They are very, very good. In some ways they are, and in some ways they're not. I recently made a loop 5x faster by writing it slightly differently. Reason? MSVC decided to emit code that messes up store forwarding (very much a microarchitectural detail). Spelling out the pointer derefs produced much better code. More specifically, the loop was loading ARGB values and storing them as BGR (yes, blitting on the CPU, don't ask). MSVC tried to be clever by storing the lower 16 bits of the ARGB value to the stack and then reading the individual bytes for writing. CPUs of course don't (usually) go to main memory when you write to memory and then read it, due to store forwarding. But that only works if your stores and loads are the same sizes - which 16 vs 8 bits are not. So the compiler somehow managed to make a 3 byte twiddle memory bound. Profile, and don't be afraid of reading some assembly.
- pjmlp 5y agoExcept inline is like register, it is only a nice request to the compiler, not an order. If you really want to inline no matter what, the only way is with compiler specific keywords/attributes.
- mike_hock 5y agoYou can care about performance without caring about "that level" of performance.
- Dylan16807 5y agoRight, but the point was only "that level" requires C.
- pjmlp 5y agoWhen one cares about that level of performance, then only straight Assembly.
- OskarS 5y ago> Doing a function call is quite expensive! Doing a function call in C/C++ is not expensive. I wish people would stop saying this, it's just not true, it's one of the most annoying myths in programming. A C function call is on the order of a tiny number of nanoseconds. Here's a benchmark to compare [1]. It's an infinitesimal amount, and it is absolutely swamped by something like a cache miss. If you eliminate one cache miss but add 50 function calls, that's probably a net benefit. The only sense in which function calls in C are "expensive" is during compilation: if a compiler can inline a function call, it can potentially do tons of new optimizations that it couldn't do before, and that can yield a huge improvment in performance. But the function call ITSELF is almost never the problem. [1]: https://quick-bench.com/q/2q8ch4HmQSpsSdrwd082NpV3KeI https://quick-bench.com/q/2q8ch4HmQSpsSdrwd082NpV3KeI
- rightbyte 5y agoSure, but if it is a call that is just not a jmp with an immediate address then the difference is more then 30% as in your example. Eg. if we force a call to eg. abs() the difference is 60%. https://quick-bench.com/q/Hpk1YFViS6lqtV5oYcXx2ZCY9us https://quick-bench.com/q/Hpk1YFViS6lqtV5oYcXx2ZCY9us Really cool site btw! But your point still stands. In my experience the greatest benefits of inlining is when range or null checks can be removed in the inlined function, not the actual call.
- OskarS 5y agoAh, good point, I missed that my version became a tail call, good catch. Still, a C function call is pushing a couple of values onto the stack then performing an unconditional jump, so it's not much worse. That site is indeed very neat! It just uses Google Benchmark in the background, but it's excellent for these kinds of discussions (and lovely to have it link directly to godbolt if you want). It's a shame that it doesn't give you the actual latency numbers like regular Google Benchmark, but I suppose that is to be expected when you're running in server VMs, those numbers aren't necessarily meaningful.
- P_I_Staker 5y ago"Everyone develops the way I do"... "embedded systems don't exist"... Typical hackernews :)