-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Communicate intent precisely.
Right now you can use @setRuntimeSafety(false) in Debug and ReleaseSafe modes to allow the optimizer to speed up particular blocks of code. This would make sense to do in a well tested high performance crypto algorithm for example. Or in general the bottlenecks of your library or program.
So the pattern here is that the build mode specifies the default, and you can override it at a per-block (or function) level. Here's a table of the parameters and the defaults that the build modes set:
| Parameter | Debug | ReleaseFast | ReleaseSafe | ReleaseSmall |
|---|---|---|---|---|
| LLVM Optimizations - improve speed, harm debugging & compile time | -O3 | -O3 | -Os | |
| Runtime Safety Checks - harm speed, harm size, improve debugging | On | On |
With @setRuntimeSafety we can make a block of code adhere to the principles of Debug even in a ReleaseFast build, and vice versa. ...to some extent - it does not affect optimizations.
But it could! LLVM supports choosing -O3, -Os, or -O0 at least at the function level.
You can probably guess what I'm leading up to here. Really instead of specifically asking to turn off safety, what we really want to communicate to the compiler is what we want to optimize for.
@optimizeFor(comptime mode: BuildMode)
Where BuildMode is already defined as @import("builtin").BuildMode:
pub const Mode = enum {
Debug,
ReleaseSafe,
ReleaseFast,
ReleaseSmall,
};And then the other issue we need to solve here is that the same intent should be communicable for types. Zig reserves the right to order fields and insert padding and such for structs, and therefore we should also allow the programmer to tell Zig what to optimize for.
For example Debug might randomly order fields to make sure one does not accidentally depend on field order. ReleaseFast might arrange fields in an order most likely to have better cache performance. ReleaseSmall might sort fields by descending alignment to minimize padding.
One little tidbit: ReleaseSmall is about generated binary size, not runtime memory size. So there is a slight disconnect here. But "small" is definitely something you would potentially want to optimize for in a struct, union, or enum. We can think about how to name the release modes and the optimization targets more coherently.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status