Conversation
This iteration already has significantly better incremental support. In fact, this PR also enables every incremental test for x86_64-linux-selfhosted and already passes all of them with this linker.
Closes #24110
This iteration already has significantly better incremental support. Closes ziglang#24110
Release Notes
The new linker can be used with -fnew-linker in the CLI, or by setting exe.use_new_linker = true in a build script.
It is already the default when passing -fincremental and targeting ELF.
The performance is fast enough that there's no longer much of a benefit to exposing a -Dno-bin build step. You might as well keep codegen and linking always enabled because the compilation speed difference is negligible, and then you get an executable at the end.
Performance Data Points
Old linker, building Zig compiler, then making a single-line change to a function, and then another:
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 18s
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 754ms
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 858ms
New linker, building Zig compiler, then making a single-line change to a function, and then another:
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 18s
└─ options success
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 73ms
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 72ms
Disabling the backend and linker entirely, building Zig compiler (type checking only), then making a single-line change to a function, and then another:
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 17s
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 70ms
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 69ms
In summary:
- incremental updates are 11 times faster.
- with the new linker, there is only a 4% slowdown compared to skipping code generation and linking entirely
EFLql
mentioned this pull request
The previous benchmarks were misleading due to the incomplete nature of the new linker, more accurate numbers reflecting the current progress are:
Old linker, building Zig compiler, then making a single-line change to a function, and then another:
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 14s
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 194ms
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 191ms
New linker, building Zig compiler, then making a single-line change to a function, and then another:
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 14s
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 65ms
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
└─ compile exe zig Debug native success 64ms
Disabling the backend and linker entirely, building Zig compiler (type checking only), then making a single-line change to a function, and then another:
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 14s
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 62ms
Build Summary: 3/3 steps succeeded
install success
└─ compile exe zig Debug native success 62ms
Similar conclusion as before, just not as extreme.
Non-incremental comparison only shows an insignificant speedup:
Benchmark 1 (13 runs): release/bin/zig build-exe -fstrip -fno-new-linker ...
measurement mean ± σ min … max outliers delta
wall_time 9.96s ± 44.4ms 9.91s … 10.1s 0 ( 0%) 0%
peak_rss 766MB ± 5.82MB 754MB … 774MB 0 ( 0%) 0%
cpu_cycles 87.1G ± 358M 86.7G … 87.9G 0 ( 0%) 0%
instructions 209G ± 12.0M 209G … 209G 1 ( 8%) 0%
cache_references 7.23G ± 15.2M 7.21G … 7.27G 0 ( 0%) 0%
cache_misses 293M ± 6.30M 286M … 307M 0 ( 0%) 0%
branch_misses 312M ± 2.19M 310M … 317M 0 ( 0%) 0%
Benchmark 2 (13 runs): release/bin/zig build-exe -fstrip -fnew-linker ...
measurement mean ± σ min … max outliers delta
wall_time 9.85s ± 21.7ms 9.83s … 9.90s 0 ( 0%) - 1.1% ± 0.3%
peak_rss 857MB ± 8.54MB 842MB … 868MB 0 ( 0%) 💩+ 11.9% ± 0.8%
cpu_cycles 87.8G ± 105M 87.7G … 88.0G 0 ( 0%) + 0.8% ± 0.2%
instructions 211G ± 16.1M 211G … 211G 0 ( 0%) 💩+ 1.1% ± 0.0%
cache_references 7.22G ± 11.5M 7.20G … 7.25G 2 (15%) - 0.1% ± 0.2%
cache_misses 295M ± 2.06M 290M … 297M 0 ( 0%) + 0.5% ± 1.3%
branch_misses 314M ± 730K 314M … 316M 0 ( 0%) + 0.7% ± 0.4%
Oops, looks like my mistake was not passing strip to old linker because I didn't realize debug info was not implemented yet
mlugg
mentioned this pull request
13 tasks