10 ms·
Mid-stack inlining in the Go compiler
- ainar-g 10y agoWhoah, nine percent? That's a lot! Now I wonder if the improvement better or worse on non-x86 platforms?
- lazard 10y agoWe measured 10% improvement on ppc64.
- chillydawg 10y ago9% faster, 15% bigger. I'll take that!
- DannyBee 10y agoFWIW: This is actually not that great, but it's a good start. You should be able to get about 15-20% with about 3-5% binary increase size. In fact, with ThinLTO, we often see that gain with binary size decrease from smart inlining choices. (The heuristics for inlining take a very very long time to get right and tune) The issue they will next hit is that inlining is going to make the compiler slower until they tune the heuristics well.
- kevincox 10y agoIf I'm understanding the increase is mostly due to the "debugging" info that is added, not necessarily due to more code.
- DannyBee 10y agoI strongly doubt this. It doesn't say this in the preso, and ... 1. The compiler is a lot slower, which is usually from code growth and not debugging info growth. If the compiler is that much slower from debugging info growth, they have larger issues :) 2. Usually people do not include debug info sizes in binary sizes, because DWARF/et al info can be stripped and put alongside the binary (IE it doesn't even have to be part of the binary)
- sythe2o0 10y agoIt does say this. One of the last slides says 4% of the additional size came from adding more debugging information, excluding anything to do with the new inlining.
- DannyBee 10y ago"If I'm understanding the increase is mostly due to the "debugging" info that is added, not necessarily due to more code. " vs " One of the last slides says 4% of the additional size came from adding more debugging information, excluding anything to do with the new inlining" So no, it doesn't say that it's "mostly due", it says ~25% is due to debugging information.
- bmm6o 10y agoIncreased sizes lead to less effective use of instruction caches. Different use cases will be impacted differently by that, so it's worth profiling your particular application, at least until the size overhead comes down.
- horsetranqs 10y agoWould they get this for free if the go compiler was just a llvm frontend?
- sheeshkebab 10y agoJvm/java had that for a while in its JIT - it's nice to see it to coming to Golang. Byproduct of that could be little hacky things like this below that make code faster by restructuring code a little https://techblug.wordpress.com/2013/08/19/java-jit-compiler-inlining/ https://techblug.wordpress.com/2013/08/19/java-jit-compiler-...
- throwawayish 10y agoIn case someone else is wondering: What is being called "mid-stack inlining" here is what is generally understood by the term "inlining".
- CUViper 10y agoThe presentation makes a distinction between mid-stack and leaf inlining, and apparently it was only done on leaf calls before because this is less confusing in backtraces.
- paulddraper 10y agothrowawayish was downvoted, but I appreciated his and CUViper's clarification. It's not some weird, exotic form of inlining; it's just a more complete version than Go used to have.
- Ericson2314 10y agoThe point is, as usual, Go is trying to catch up to what everyone else has had for years. The use of non-standard terminology here is suspicious, raising the question that the Go people are trying to hide the fact that they are playing catch-up.
- jgalt212 10y ago> The point is, as usual, Go is trying to catch up to what everyone else has had for years. As far as programming languages go, Go is very new. Of course, there will be a number of areas that still need to be optimized or fully fleshed out. I think the Go compiler has only been written in Go for about a year. I'm sure you you find this pretty lame as well.
- weberc2 10y agoI don't think anyone is pretending that Go is a decades-old language. What is the standard term for this kind of inlining which would distinguish it from the inlining already present in the compiler?
- micah_chatt 10y agoWhat impact would that have on build times? I know a lot of work has gone into getting back to 1.4 build times, but would the added work of inlining prolong builds?
- lazard 10y agoThe compiler got a bit slower: https://github.com/golang/go/issues/19386 https://github.com/golang/go/issues/19386 Those numbers are just for my CLs that fix stack traces but with mid-stack inlining still off. Turning it on makes builds noticeably slower: $ time ./make.bash real: 45.32s user: 118.67s cpu: 5.85s $ time GO_GCFLAGS='-l=4' ./make.bash real: 64.51s user: 167.04s cpu: 7.12s We'll need to tweak the inlining heuristic to find a good balance between performance, build times, and binary size.
- simonz05 10y agoBut then the compiler gets faster once you compile it with these new improvements. Is that accounted for in the issue?
- Sunset 10y agoPlease have a switch where I can sacrifice build time for maximum possible runtime benefits.
- chriswarbo 10y agoThe compile-time/run-time tradeoff is interesting. Getting the "maximum possible runtime benefits" probably calls for https://en.wikipedia.org/wiki/Superoptimization https://en.wikipedia.org/wiki/Superoptimization :)
- spullara 10y agoIt doesnt look like this solves inlining library calls?
- koenigdavidmj 10y agoGo statically links to all Go libraries, and only dynamically links when interfacing with C code. (As of the last time I used it, a couple years ago; this may have changed since then.)
- spullara 10y agoThat doesn't really answer whether it can inline library functions. The fact that it statically links means it potentially could inline methods it finds in them but I don't think that it does currently since it appears that this inline functionality works when compiling source.
- ekiru 10y agoIt can inline library functions, since, at latest, 1.4.2 (this is just what I happened to have handy on this computer). It's pretty easy to test by writing a package containing a simple function like "func Square(x int) int { return x * x }", compiling a main package that imports that package and calls Square, and then disassembling the executable to see whether it calls Square or inlines it.
- pjmlp 10y agoGo nowadays supports dynamic linking, just plugins aren't 100% supported across all targets.
- aclements 10y agoGo already performs cross-package inlining, so it can already inline library calls. (This is relatively easy to do in Go compared to other languages because packages must form a DAG. Compiling package A writes out enough information in the object file for A that compiling package B that depends on A can inline calls to functions in A.)
- YesThatTom2 10y agoThe presentation redacted the stats about how this affects Google performance. I bet it saves enough CPU hours to pay the author's salary many many many times over. Good job!
- edgyswingset 10y agoMaybe? I'm under the impression that the vast majority of Google's software is not written in Golang, though.
- YesThatTom2 10y agoAgreed.
- YesThatTom2 10y agoAgreed.
- SEJeff 10y agoBut even 1% of their software being go would still see more use than most software you or I write in our lifetimes. dl.google.com has been golang since 2013. Imagine the traffic that application gets! https://talks.golang.org/2013/oscon-dl.slide#1 https://talks.golang.org/2013/oscon-dl.slide#1
- zamalek 10y agoThis is absolutely fantastic work. Since I've learned about continuation passing style (which Go channels could probably be formally transformed into), I've been convinced that there's a better way to do codegen. Better calling convention, better stack representation, better instruction architecture; I'm not yet sure - it's a nag continuously at the back of my mind, almost as though it's at the tip of my tongue. In this specific case, it must surely be possible to inline a continuation with some foreign architecture. I'd love to see some literature on the more experimental end of this stuff, if anyone has it.
- pjmlp 10y agoAre you aware of "Compiling with Continuations? https://www.amazon.com/Compiling-Continuations-Andrew-W-Appel/dp/052103311X https://www.amazon.com/Compiling-Continuations-Andrew-W-Appe...
- hinkley 10y agoThat's an interesting read. One of only a handful of tech books I've read twice. It's thin and doesn't repeat itself all that much so if you read it twice it's still faster than reading most tech books once. More recently though I heard someone proved mathematically that CPS can be transformed one-for-one into one of the more conventional models. That doesn't mean it might not still be easier for the humans to deal with however.
- tmzt 10y agoSomething like this, in Rust? https://aturon.github.io/blog/2016/08/11/futures/ https://aturon.github.io/blog/2016/08/11/futures/
- dap 10y agoThis is interesting work! That said, it's a little disappointing when runtimes require custom algorithms or metadata to walk the stack and construct a stack trace. It makes it harder to build debuggers that grok the state of multiple runtimes (e.g., the Go code and the C code in the same program). This also affects runtime tracing tools like DTrace, which by construction can't rely on runtime support for help.
- lazard 10y agoThe plan is to add inlining information to the DWARF tables so that debuggers and other tools can take advantage of it.
- aclements 10y agoWe plan to expose all of the inlining information in the DWARF tables so debuggers won't have any problems with this. Internally, the runtime uses a different representation just so we can make it more compact and optimized for the runtime's exact needs. This way, you can also strip the debug info without breaking the runtime's own ability to walk stacks.
- snovv_crash 10y agoIt looks like most of the improvements are in string formatting problems. I'm curious if better heuristics will help other areas as well.
- cetinsert 10y agoAs someone who now professionally uses go on a range of mips devices, I, for one, do care about any binary size increases!