←back to thread

302 points Bogdanp | 10 comments | | HN request time: 1.174s | source | bottom
Show context
taylorallred ◴[] No.44390996[source]
So there's this guy you may have heard of called Ryan Fleury who makes the RAD debugger for Epic. The whole thing is made with 278k lines of C and is built as a unity build (all the code is included into one file that is compiled as a single translation unit). On a decent windows machine it takes 1.5 seconds to do a clean compile. This seems like a clear case-study that compilation can be incredibly fast and makes me wonder why other languages like Rust and Swift can't just do something similar to achieve similar speeds.
replies(18): >>44391046 #>>44391066 #>>44391100 #>>44391170 #>>44391214 #>>44391359 #>>44391671 #>>44391740 #>>44393057 #>>44393294 #>>44393629 #>>44394710 #>>44395044 #>>44395135 #>>44395226 #>>44395485 #>>44396044 #>>44401496 #
ben-schaaf ◴[] No.44393294[source]
Every claim I've seen about unity builds being fast just never rings true to me. I just downloaded the rad debugger and ran the build script on a 7950x (about as fast as you can get). A debug build took 5s, a release build 34s with either gcc or clang.

Maybe it's a MSVC thing - it does seem to have some multi-threading stuff. In any case raddbg non-clean builds take longer than any of my rust projects.

replies(3): >>44394691 #>>44400609 #>>44405178 #
1. maccard ◴[] No.44394691[source]
I use unity builds day in day out. The speed up is an order of magnitude on a 2m+ LOC project.

If you want to see the difference download unreal engine and compile the editor with and without unity builds enabled.

My experience has been the polar opposite of yours - similar size rust projects are an order of magnitude slower than C++ ones. Could you share an example of a project to compare with?

replies(2): >>44397204 #>>44397303 #
2. almostgotcaught ◴[] No.44397204[source]
How many LOC is unreal? I'm trying to estimate whether making LLVM compatible with UNITY_BUILD would be worth the effort.

EDIT: i signed up to get access to unreal so take a look at how they do unity builds and turns out they have their own build tool (not CMake) that orchestrates the build. so does anyone know (can someone comment) whether unity builds for them (unreal) means literally one file for literally all project sources files or if it's "higher-granularity" like UNITY_BUILD in CMake (i.e., single file per object).

replies(2): >>44397636 #>>44399260 #
3. ben-schaaf ◴[] No.44397303[source]
> If you want to see the difference download unreal engine and compile the editor with and without unity builds enabled.

UE doesn't use a full unity build, it groups some files together into small "modules". I can see how this approach may have some benefits; you're trading off a faster clean build for a slower incremental build.

I tested compiling UnrealFrontend, and a default setup with the hybrid unity build took 148s. I noticed it was only using half my cores due to memory constraints. I disabled unity and upped the parallelism and got 182s, so 22% slower while still using less memory. A similarly configured unity build was 108s, so best case is ~2x.

On the other hand only changing the file TraceTools/SFilterPreset.cpp resulted in 10s compilation time under a unity build, and only 2s without unit.

I can see how this approach has its benefits (and drawbacks). But to be clear this isn't what projects like raddbg and sqlite3 are doing. They're doing a single translation unit for the entire project. No parallelism, no incremental builds, just a single compiler invocation. This is usually what I've seen people mean by a unity build.

> My experience has been the polar opposite of yours - similar size rust projects are an order of magnitude slower than C++ ones. Could you share an example of a project to compare with?

I just did a release build of egui in 35s, about the same as raddbg's release build. This includes compiling dependencies like wgpu, serde and about 290 other dependencies which add up to well over a million lines of code.

Note I do have mold configured as my linker, which speeds things up significantly.

replies(1): >>44403925 #
4. Culonavirus ◴[] No.44397636[source]
At least 10M (from what I remember, maybe more now)
5. maccard ◴[] No.44399260[source]
The build tool groups files into a roughly equivalent size based on file length, and dispatches compiles those in parallel.
replies(1): >>44399410 #
6. almostgotcaught ◴[] No.44399410{3}[source]
how many groups do people usually use to get a fast build (alternatively what is the group size)?
replies(1): >>44400955 #
7. maccard ◴[] No.44400955{4}[source]
It’s about 300kb before pre processor expansion by default. I’ve never changed it.
8. maccard ◴[] No.44403925[source]
I think the definition of unity build is sufficiently unclear that it can be used as a pro or a con. It’s one of the problems with c++ - there’s no default build tool to compare with. II’d argue that a single unity blob with one compiler invocation isn’t a fair comparison and that when you made a token effort to configure the unity build you saw a 2x speed up.

I’m the tech director for a game studio using unreal and we spec the dev machines with enough memory to avoid that pressure - we require 2.5GB/Core, rounded up. Right now we’re using i9 14900k’s with 128GB RAM. We were on 5950x with 64GB before this.

I tried egui last night but failed to build it due to missing dependencies, but I’ll see if I can get it running on Monday. I’d also love to see what raddbg would be like if we split it into even 4 compilation units

replies(1): >>44405080 #
9. ben-schaaf ◴[] No.44405080{3}[source]
> II’d argue that a single unity blob with one compiler invocation isn’t a fair comparison and that when you made a token effort to configure the unity build you saw a 2x speed up.

Most certainly an unfair comparison; I did not know that "unity build" also referred to a hybrid setup. I've only seen people advocate for a single translation unit approach, and that's always just plain slow.

Personally I'll almost always prefer faster incremental compilation; thankfully my work's clean builds only take 30 seconds.

> I’d also love to see what raddbg would be like if we split it into even 4 compilation units

Should be a minimum of 32x faster just building in parallel with our hardware ;)

Unfortunately raddbg suffers from unity-build-syndrome: It has headers but they're missing definitions, and .c files are missing includes.

replies(1): >>44405559 #
10. maccard ◴[] No.44405559{4}[source]
If my clean builds were 30 seconds I’d prefer incremental performance too. Our precompiled headers take longer than that. A clean ue5 editor build with precompiled headers, adaptive unity builds and optimisations disabled takes 20 minutes or so. Incremental changes to game projects are usually prettt quick - under 5 seconds or so (which is fast enough when the whole thing takes 30+ seconds to boot anyway.

> Unfortunately raddbg suffers from unity-build-syndrome: It has headers but they're missing definitions, and .c files are missing includes.

We run a CI build once a week with unity disabled to catch these issues.

> Should be a minimum of 32x faster just building in parallel with our hardware ;)

My experience here is that parallelism is less than linear and avoiding repeated work is super-linear - there’s a happy medium. If you had 128 files and 32 cores it’s probably fast to compile in parallel, but likely even faster if you can just dispatch 32 “blobs” and link them at the end.