Live data from Hacker News

Two studies in compiler optimisations

hmpcabral.com

21–27 of 27 posts

Re: Two studies in compiler optimisations

#21
post #9

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

It feels like a leaky abstraction, and similarly implies there should be some way to drop down a layer and work directly with what’s beneath. Something in between C and non-portable assembly. Asserting retroactively that compilers produce the correct assemvbly feels like just plain giving up on everything in between. Surely the best we can do isn’t a bunch of flaky weirdly interacting optimizations, UB footguns every…

> Something in between C and non-portable assembly.

Writing your own LLVM passes?

Re: Two studies in compiler optimisations

#22

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

I think a better approach might be automated performance regression tests. That's checking the property you probably actually care about directly (performance) and leaves the compiler (and other engineers) some leeway to do better without breaking the test.

Actually setting up a robust system for perf regression tests is tricky though...

Re: Two studies in compiler optimisations

#23

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

It is brittle and a leaky abstraction. Code is already too complex, and correctness and time complexity are far more important than these micro-optimizations. Although I think your language feature seems reasonable.

Re: Two studies in compiler optimisations

#24
post #9

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

It feels like a leaky abstraction, and similarly implies there should be some way to drop down a layer and work directly with what’s beneath. Something in between C and non-portable assembly. Asserting retroactively that compilers produce the correct assemvbly feels like just plain giving up on everything in between. Surely the best we can do isn’t a bunch of flaky weirdly interacting optimizations, UB footguns every…

I have written a compiler for a language at more or less this abstraction level. It provides access to 16 general purpose registers and a set of virtual instructions that operate on these registers. I program on an intel mac so the virtual instructions all map directly to x86_64 instructions, but it would be very straightforward to write an arm backend that may compose multiple arm instructions for the equivalent x86_64 behavior. I also could support virtual registers for platforms with fewer than 16 registers.

Having this compiler, which is extremely fast (it is self hosted and self compiles its own 9750K line source file in 15ms on my 2019 macbook pro and I've seen throughout ranging from 500K to 10M lines per second for other programs), I have little interest in ever using LLVM again. I would rather just write optimal code than pray that LLVM does a good job for me. For equivalent programs, I find LLVM can be anywhere from 50-10000x slower than my compiler and doesn't necessarily produce better code. I can produce examples of LLVM code becoming significantly worse at -O2 than at -O0.

The only real utility LLVM offers me at this point is that I could use it to figure out what an optimal solution to a small subprogram might be by compiling a small c program and inspecting the output. Then I can just directly write the optimal solution instead of being perpetually bogged down by llvm's bloat as well as also being exposed to unexpected regressions in the optimizer and/or having to learn its strange incantations to get desired performance.

Re: Two studies in compiler optimisations

#25

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

(Author here)

>It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes.

I would say the main takeaway is actually to not do that, precisely because it's brittle, difficult to understand, and can backfire by making things harder for the compiler. As I point out at the end, the vast majority of developers will be better served by sticking to common idioms and making their intent as clear as possible using language facilities, rather than trying to outsmart the compiler or, conversely, relying excessively on the optimiser as a magic black box.

That being said, I do find it helpful to understand the broad strokes of the optimisation pipeline (things like "callees are optimised before callers", "maintaining invariants enables more simplifications", or "early simplifications are better") to make the most of it. Like with any other tool, mastery means letting it do its job most of the time but knowing when and where to step in if necessary.

Re: Two studies in compiler optimisations

#26

> Here, the simplification analysis uses the conditional hidden in the assert() macro to figure out that we only execute the urem instruction if cur It surprises me that the compiler doesn't still take the inference from the assert and just disable emitting the code to perform the check. Over the last 15 years I've worked on many codebases that are written with unnecessary asserts, partly as documentation, but maybe…

There's an interesting comment on this over on Lobsters: https://lobste.rs/s/e4y5ps/two_studies_compiler_optimisation...

Re: Two studies in compiler optimisations

#27

Interesting. It all seems very brittle, though. And that something has gone very wrong with our ecosystem of tools, languages, and processes when it becomes advisable to massage source until specific passes in a specific version LLVM don't mess things up for other passes. Not picking on the OA in the slightest; just thinking in terms of holistic system design. If you know what you want to happen, and you are smart en…

It is brittle and a leaky abstraction. Code is already too complex, and correctness and time complexity are far more important than these micro-optimizations. Although I think your language feature seems reasonable.

It depends on your use case, as always. Correctness is not always black and white (hence my favourite compilation flag, -funsafe-math-optimizations) and time complexity can be misleading (O(log N) with a large base is O(1) in practice), but a correct, theoretically optimal algorithm might still be leaving a lot of performance on the table. If you're a hyperscaler, a high-frequency trader, or perhaps a game programmer pushing the limits of the platform, small gains can accumulate meaningfully, as can the thousand cuts caused by small inefficiencies spread out over the codebase.
Post reply on HN