Stream: contributing

Topic: approach to optimization


view this post on Zulip Anton (Feb 01 2025 at 13:46):

Before we start on rewriting the compiler in Zig I'd like us to agree on our approach to optimization of runtime. I feel we currently have substantial differences between individuals as to where compiler runspeed falls on the priority ladder.

One important note; the consensus here seemed to be that we want to write small compiler passes. With the current compiler I believe we've taken the approach that we plan things for maximum execution speed because it's too hard to change it later. But with small passes this does not seem to apply, they should be much easier to re-write for execution speed if that pass is a serious bottleneck.

I would personally always prioritize correctness, maintainability~simplicity~debugability and error message quality over run speed. I think we should not allow any optimization that complicates the code in a pass that is nowhere close to being the bottleneck pass. Any optimization that does meet this standard should be proven to be beneficial through benchmarks before it is merged.

What do you think?

view this post on Zulip Anthony Bullard (Feb 01 2025 at 13:55):

I think you just, for each pass, try to make the fastest possible pass implementation you can that is simple to understand, easy to debug, and a joy to maintain.

So for instance, Arena allocation makes sense and is easy to reason about and provides great performance. In some cases SoAs can have the same qualities (even if they can take some adjustment to those not familiar with the pattern). But we just avoid performance optimization patterns that sacrifice those other two.

view this post on Zulip Richard Feldman (Feb 01 2025 at 14:17):

some thoughts on passes:

view this post on Zulip Richard Feldman (Feb 01 2025 at 14:24):

some thoughts on parallelization:

view this post on Zulip Richard Feldman (Feb 01 2025 at 14:48):

(these are coming in a sporadic order because we just started potty training today and I'm writing them in between cleaning up accidents :joy:)

view this post on Zulip Richard Feldman (Feb 01 2025 at 15:34):

some thoughts on memory allocation and data structures:

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:19):

One of the really nice things about working with mlir over the years is that I think it gets a clear priority correct. First figure out your IR (that is your fundamental interface). Then right passes that operate over IRs. If constraints change enough consider adding a new IR and changing to it. If not, it is fine to add more details to the same IR or save side band info.

Any stage can be a theoretically cutting point for writing the ir to disk and caching. On top of that mlir can auto parallelize to some extent. Though that mostly depends on passes running patterns on individual IR nodes instead of larger groups (which isn't always practical).

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:20):

I think we fundamentally need to focus on our IRs, our interfaces between different stacks of the compiler and. Not writing ourselves into a box that we can't easily get out of

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:21):

We have some ideas about where the North Star is for the compiler. Our work should be align with the idea of reaching the North Star. We want to right the cleanest thing possible that allows for easily taking steps towards optimal.

view this post on Zulip Richard Feldman (Feb 01 2025 at 16:22):

yeah, and then later if we want to merge some of them together to improve performance, we can do that incrementally and after we've already gotten things correct

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:22):

So it isn't strictly about simple. It is about correct now, but also easy to improve upon

view this post on Zulip Sam Mohr (Feb 01 2025 at 16:23):

Totally agreed. You weren't there for the meeting, but that's what I wrote in Rust for the post-typechecking part of the compiler: a set of IRs for each of the stages. By next Saturday, my hope is to have the IRs for all of the stages of the compiler (not just the build part like before) translated to Zig so we can collaborate on it and agree what this all should look like.

view this post on Zulip Sam Mohr (Feb 01 2025 at 16:24):

If anyone wants to work on that on their own in parallel, go for it, it's valuable to have different people try to come up with these IRs separately so we can see what the good ideas we agree on are.

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:24):

So in my mind the two most important pieces outside of correctness are making the IR and passes have a CPU/memory friendly core along with making splits in places that will help enabe improvements in the future (parallelism, caching, etc).

view this post on Zulip Richard Feldman (Feb 01 2025 at 16:25):

that's almost exactly what I advocated for in the meeting :smiley:

view this post on Zulip Richard Feldman (Feb 01 2025 at 16:25):

focus on the boundaries

view this post on Zulip Richard Feldman (Feb 01 2025 at 16:25):

and dependencies

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:27):

Yeah, I guess I just add on top CPU/memory friendly core design.

Then all the correctness, debugability simplicity,, etc without too much concern for the rest of the performance.

view this post on Zulip Brendan Hansknecht (Feb 01 2025 at 16:27):

But yeah making good bones first.

view this post on Zulip Agus Zubiaga (Feb 02 2025 at 00:30):

Richard Feldman said:

Yeah, I think this can even help debugging because you can gather more information from just the value without having to look it up in a side table. For Purity Inference, I reserved one bit of Symbols as a !-prefixed flag and it greatly simplified the implementation overall.


Last updated: Jul 06 2025 at 12:14 UTC