What is the difference between the /Ox and /O2 compiler options?
Asked Answered
M

2

82

Microsoft's C++ compiler (cl.exe, as included with Visual Studio) offers several optimization switches. The difference between most of them seems self-explanatory, but it's not clear to me what the difference is between /O2 (which optimizes code for maximum speed) and /Ox (which selects "full optimization").

I've tried reading the documentation for the /Ox option, and it seems to confirm that this switch also enables optimizations for maximum speed, rather than size:

The /Ox compiler option produces code that favors execution speed over smaller size.

But in particular, the following statement under the "Remarks" section caught my eye:

In general, specify /O2 (Maximize Speed) instead of /Ox.

So my question is, why should one generally favor /O2 over /Ox? Does the latter option enable a particular optimization known to cause unforeseen bugs or otherwise unexpected behavior? Is it simply that the amount of optimization to be gained is not worth the additional compile time? Or is this just a completely meaningless "recommendation" resulting from the fact that /O2 is the default option in VS?

Mesocratic answered 21/2, 2011 at 7:25 Comment(0)
R
56

Asha's answer cites a blog post about Visual Studio 2005, and is rather out of date.

The latest version of the documentation is available here:

According to those:

You may additionally be interested in /GS- which turns off security checks around the stack, which can be a significant performance hit (see the MS docs for /GS).

You should benchmark your specific application, as ever.

Raft answered 2/4, 2015 at 13:24 Comment(2)
Wrt. your take away, that /O2 may imply /Gs0 ... see my "doubts": #42343431Undernourished
/O2 does not appear to imply /Gs (i.e. /Gs0) in latest versions of Visual Studio: learn.microsoft.com/en-us/cpp/build/reference/…Punctuate
P
59

I found it here:

Ox and O2 are almost identical. They differ only in the fact that O2 also throws GF and Gy. There is almost no reason to avoid throwing these two switches.

Pentapody answered 21/2, 2011 at 7:33 Comment(4)
Nice job! I guess I just didn't search quite long enough myself. Interesting that the documentation makes it appear that /Ox is a higher level of optimization than /O2. It seems that both of those would provide at least a theoretical performance boost.Mesocratic
Apparently so.. It seems using the /OPT:REF linker option along with /Gy would help in removing the unreferenced functions from the final exe. I'm not too sure about how useful is /GF is though.Pentapody
/GF is great - it pools all identical string literals in a read-only memory region. So if you have some literal in multiple areas of code you'll only have it once in the executable which reduces the image size. And if your code attempts to modify it you'll get Access Violation which protects you against dumb errors.Stier
It's worth noting that, according to Stephan T Lavavej (the STL lead for MS VC++), Microsoft's compiler backend team considers /Ox "an evil switch from beyond time" and urges everyone to use /O2 instead of /Ox.Punctuate
R
56

Asha's answer cites a blog post about Visual Studio 2005, and is rather out of date.

The latest version of the documentation is available here:

According to those:

You may additionally be interested in /GS- which turns off security checks around the stack, which can be a significant performance hit (see the MS docs for /GS).

You should benchmark your specific application, as ever.

Raft answered 2/4, 2015 at 13:24 Comment(2)
Wrt. your take away, that /O2 may imply /Gs0 ... see my "doubts": #42343431Undernourished
/O2 does not appear to imply /Gs (i.e. /Gs0) in latest versions of Visual Studio: learn.microsoft.com/en-us/cpp/build/reference/…Punctuate

© 2022 - 2024 — McMap. All rights reserved.