Tricks to improve optimization level?

Hi,

I am compiling my program as follows:

zig build-exe -Doptimize=ReleaseFast z.zig

But when I look at the assembly language generated for the functions in my program, it appears to be as though I used the equivalent of ‘-g -O0’ on a C compiler. ls there a way I can improve my optimization level by adding a better option to the command line above? If not, could someone point me to a Zig build script that might improve optimization?

PS I am running the the “aarch64 Linux” zig executable retrieved from the Download page at Download ⚡ Zig Programming Language .

1 Like

Can you show the code and the assembly?

-Doptimize=ReleaseFast is for zig build when using b.standardOptimizeOption() (i.e. when you are using the zig build system)

When using zig build-exe, zig build-lib, etc directly you want -OReleaseFast instead.

It’s unfortunately a common mistake and doesn’t provide feedback because -D[macro]=[value] is a valid option to zig build-exe (Define C [macro] to [value] (1 if [value] omitted))

16 Likes

Much better! I don’t see any advanced FP optimizations, but the FP is reasonably good. The integer optimizations and branching are markedly better. I’ll have a better idea when I finish porting my app.

I struggled a bit with parameter passing of multidimensional array slices today, but I should definitely finish the first cut of my port by Thursday, no matter what else I might trip over.

It would actually be nice if the --release=[fast|safe|small] option would work anywhere.

6 Likes

As far as I understand, --release is also a rather confusing flag that was originally (and still is?) only intended for use by “system package maintainers”

For an example of something that might be unexpected, if the preferred_optimize_mode field is set in StandardOptimizeOptionOptions, then the <mode> in --release=<mode> is silently ignored (and this behavior is intentional).

Relevant issues/PRs:

Personally, I avoid --release/preferred_optimize_mode entirely. Somewhere down the line hopefully this stuff will become less confusing, though (as mentioned in this PR, breaking changes to these APIs in the future are very likely).

3 Likes

Well that is confusing indeed. I totally thought the --release was added to finally clean up the -O vs -D mess…

IMHO: ideally though the -D syntax would be replaced with directly accepting the name in b.option() e.g. a custom option -Dwgpu would become --wgpu, and -Doptimize=[ReleaseFast|ReleaseSmall|ReleaseSafe] would become --optimize=[none|fast|small|safe]

4 Likes

Read here:

As tempting as this is, the -D syntax has the great advantage that it’s a clean namespace. If the compiler were to accept --whatever, then we have to choose among some bad options: either code simply isn’t allowed to use a b.option which matches any of the builtin flags (and there are a lot), or we still need -Dwhatever, and there’s just two ways to do things.

Worse, if you grabbed an option and Zig added a flag with that same name, now your library won’t compile, it’s breaking transitives, you need to pick a new name and tell everybody.

Also, this way if you’re looking at a zig build invocation in a makefile or something, you know what’s a user option right away, without having to have complete knowledge of the (many) flags in use by the rest of the system.

All in all, I think having a consistent prefix for project-specific options is better. It’s unfortunate that the different verbs have different ways of doing something as basic as setting the release mode, but that will eventually be refactored, I’m sure. I don’t think that having to type D instead of - to get a string of the same length is worth it.

6 Likes