Open Vexu opened 1 year ago
I like this proposal and have often wanted this exact thing - ("release a release-fast build for the speed but keep certain less expensive runtime safety checks enabled like reached unreachable code") - e.g. that would allow a release-fast build where assert
still asserts.
With this proposal would there be a corresponding way to use @setRuntimeSafety
(or something like it) to individually enable/disable certain checks per-scope?
With this proposal would there be a corresponding way to use
@setRuntimeSafety
(or something like it) to individually enable/disable certain checks per-scope?
I did consider it but it doesn't seem as useful and if absolutely necessary could mostly be achieved by wrapping the operation causing the safety check in a block with @setRuntimeSafety
.
With this proposal would there be a corresponding way to use
@setRuntimeSafety
(or something like it) to individually enable/disable certain checks per-scope?I did consider it but it doesn't seem as useful and if absolutely necessary could mostly be achieved by wrapping the operation causing the safety check in a block with
@setRuntimeSafety
.
I think that's quite a noisy and laborious-to-implement solution though. For example, a project may determine (for the entire project, or for a specific scope) that bounds-checking is a worthwhile safety check to use, but that overflow checks aren't. This wouldn't be very feasible without a specific solution, on a scope-based level. I think there should be a way to set the default safety checks for a build mode (or perhaps a custom build mode?) in build.zig
, and then on a scope-level, with something like a more expressive @setRuntimeSafety
.
I like this proposal and have often wanted this exact thing - ("release a release-fast build for the speed but keep certain less expensive runtime safety checks enabled like reached unreachable code") - e.g. that would allow a release-fast build where
assert
still asserts.
Would it allow a ReleaseSafe build, where certain sections of the code, e.g. the sections that have the most impact on performance, can be optimized by having the checks removed / optimized away by the compiler?
I wanted to see how enabling safety checks for unreachable would affect the compiler so I made an MVP of this.
zig-out/bin/zig
dcaf43674e35372e1d28ab12c4c4ff9af9f3d646
build-fast/bin/zig
dcaf43674e35372e1d28ab12c4c4ff9af9f3d646 + https://github.com/Vexu/zig/tree/safety-opt
It seems that by default release fast builds include debug info now:
# with debug info
261M zig-out/bin/zig
261M build-fast/bin/zig
# stripped
150M zig-out/bin/zig
150M build-fast/bin/zig
Equivalent performance:
Benchmark 1 (3 runs): zig-out/bin/zig test test/behavior.zig --test-no-exec -I test
measurement mean ± σ min … max outliers delta
wall_time 6.98s ± 30.8ms 6.96s … 7.02s 0 ( 0%) 0%
peak_rss 438MB ± 429KB 437MB … 438MB 0 ( 0%) 0%
cpu_cycles 27.1G ± 125M 27.0G … 27.2G 0 ( 0%) 0%
instructions 35.9G ± 17.9M 35.9G … 35.9G 0 ( 0%) 0%
cache_references 658M ± 7.81M 649M … 663M 0 ( 0%) 0%
cache_misses 25.3M ± 447K 24.8M … 25.7M 0 ( 0%) 0%
branch_misses 180M ± 754K 180M … 181M 0 ( 0%) 0%
Benchmark 2 (3 runs): build-fast/bin/zig test test/behavior.zig --test-no-exec -I test
measurement mean ± σ min … max outliers delta
wall_time 7.08s ± 64.7ms 7.03s … 7.15s 0 ( 0%) + 1.4% ± 1.6%
peak_rss 439MB ± 1.48MB 438MB … 441MB 0 ( 0%) + 0.3% ± 0.6%
cpu_cycles 27.6G ± 254M 27.3G … 27.8G 0 ( 0%) + 1.7% ± 1.7%
instructions 36.3G ± 21.6M 36.3G … 36.3G 0 ( 0%) + 1.1% ± 0.1%
cache_references 674M ± 543K 673M … 674M 0 ( 0%) + 2.4% ± 1.9%
cache_misses 26.1M ± 1.27M 25.2M … 27.6M 0 ( 0%) + 3.3% ± 8.5%
branch_misses 184M ± 1.49M 182M … 185M 0 ( 0%) + 1.8% ± 1.5%
Hitting an assertion failure (#18273):
$ zig-out/bin/zig build-obj a.zig
Segmentation fault (core dumped)
$ build-fast/bin/zig build-obj a.zig
thread 204448 panic: reached unreachable code
Unwind information for `:0xa0d9b61` was not available, trace may be incomplete
Aborted (core dumped)
Currently runtime safety can be controlled with two mechanisms:
@setRuntimeSafety
for toggling all safety checks per scopeBut sometimes when you're pre 1.0 and have known issues you might want to release a release-fast build for the speed but keep certain less expensive runtime safety checks enabled like
reached unreachable code
andattempt to use null value
.This could be achieved with a new compiler flag which would allow you to toggle runtime safety checks regardless of those two mechanisms in a similar way to CPU feature flags:
-OReleaseFast+unrechable+null_value
-ODebug-integer_overflow-shift_overflow