3 ms·
I've also seen that -Os with GCC produces significantly slower code in pretty much all use cases I've looked at it on (Game rendering code, optimizing shader co
by kimixa 3y ago
I've also seen that -Os with GCC produces significantly slower code in pretty much all use cases I've looked at it on (Game rendering code, optimizing shader compiler, GPU drivers). And that's on mobile devices where you might expect to be more cache/memory bandwidth limited.
I believe the general idea that -Os was often the best choice was popularized as it became the default on MacOS, which uses Clang, which may bias it's optimization options differently. And Clang has had the -Oz option for if you really want to focus on total size, trading possibly lower performance, for quite a while. GCC only introduced the same relatively recently in gcc 12. So maybe it'll change the bias of Os going forward?
EDIT: Though I'm not sure about the disassembler on godbolt - I tried seeing if the c++ std::accumulate function would affect code generation, and the disassembled code looks incomplete, and doesn't match the compiler assembler output (by disabling "Compile to Binary Object") at all
[0] https://godbolt.org/z/5443fo75n https://godbolt.org/z/5443fo75n
- kragen 3y agohey, my reply seems to have been lost! i'll try again yes, using -Os does seem to have been my main problem! possibly in the past gcc's optimization wasn't as flexible and so couldn't trade off performance for code size as effectively but what surprised me in this case was not that -Os was reducing size at the expense of speed; it's that it was failing to apply a well-known, widely-applicable optimization that both reduces size and improves speed getting down to the 4-instruction form of the loop does require an optimization that increases size while (usually) improving speed: transforming while (x) y; into if (x) do y; while (x);, which costs four bytes in this case (because the beq/bne doesn't fit into a compressed instruction; risc-v 2-byte compressed branches can only test a single register, so you only have c.beqz and c.bnez)
- kimixa 3y agoYou can control most of the optimization flags separately, I think most are listed under the various levels here [0], might be interesting to see what causes the difference, or if it's one of the unspecified "tuning values". [0] https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
- dzaima 3y agoI haven't bothered to use -Os much (outside of places where performance decidedly does not matter); it seems fairly clear to me that code with like any amount of hot spots (i.e. most code) would greatly suffer. I wonder how different would things be if it was more common to select optimization level per function, instead of for the whole project (gcc allows it, clang has only a thing to disable all optimizations on a function).
- kragen 3y agointeresting, i also see truncated (or corrupted?) output with 'compile to binary object' on that file. 'link to binary' gives better results