For software performance, can you always trust inlining?
lemire.me
lemire.me
What it ended up with is a bunch of absolutely enormous modules, each generating tens of megabytes of mostly identical code, but with the leaf functions in each case handling floats, ints, strings, etc.
Removing some of these inline directives probably would not impact the code at all, since most of the inlined code was cold. But it would likely benefit build performance quite a bit. It might even improve runtime performance by putting less pressure on the cache.
This is probably not a surprise, but inlining is best for hot leaf code. Cold code should probably not be inlined unless it is used exactly once.
Heck with explicit template instantiation the generic code may not even be in the same translation unit as the calling code. At that point it'd require link time optimization to inline it.
Maybe I’m misunderstanding you.
> This is true in monomorphized languages like Rust
It's not necessarily true for monomorphized code. Inlining is enabled by monomorphization, but is not required.
You can see it with templates in C++: function template instantiations aren't always inlined. They are instantiated in every TU separately, if they are defined in headers, but then they may be called in this TU just like any other function without inlining. This requires the linker to deduplicate the instantiations later. In another scenario you may declare a function template in a header without the implementation, putting the implementation in a CPP file along with explicit instantiation. In that case the compiler is not able to inline this function in another TU (without LTO).
As for Rust, Rust is not universally monomorphized. The user of generic code in Rust gets to decide whether they want to use monomorphization or vtables, regardless of the ideas of the author of said generic code.
this thread is about function call inlining.
https://clang.llvm.org/docs/AttributeReference.html#always-i...
Edit: it is correct though, that the inline keyword often is a neccessity to allow the compiler to inline in the first place. After all, the compiler can only inline a function at the callsite, when both are in the same translation unit. Either the function is only used in one translation unit, or it has to be defined as inline (or worse as hidden to the linker by static or anonymous namespace). Disregarding LTO, of course.
Not so much a possibility as a certainty on modern processors. Easiest way to tell: run it through perf stat and read the output.
Well… I’m definitely no expert, but I don’t think that’s great reasoning. His code has jumps in it that appear to be loops, just because the code is tighter doesn’t mean I can infer anything about where it will jump and how many times JUST based on how many lines or how “tight” it is.
He’s right I’m sure that his second example is faster, I just don’t like that for an assumption.