Differencebetween the /Ox and /O2 Compiler Options

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

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:

  • /Ox: https://msdn.microsoft.com/en-us/library/59a3b321.aspx
  • /O2: https://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx

According to those:

  • /Ox/Og /Oi /Ot /Oy /Ob2
  • /O2 → the same, but further adds /Gs /GF /Gy

    • /GF eliminates duplicate strings
    • /Gy does function level linking

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.

Visual Studio 2013 optimization flags (/O2 vs /Ox)

As Arkanosis pointed out correctly, when going from /O2 to /Ox, you disable /Gs, /GF, /Gy. The question is which of these flags may increase execution speed?

/Gs is identical to /Gs0 and can have negative impact on performance. See below the description on MSDN.

activates stack probes for every function call that requires storage
for local variables. This can have a negative impact on performance

/GF eliminates duplicate strings (constants) - called string pooling. This will reduce the code size. A lower code could produce lower number of instruction cache misses but I doubt this effect is observable on most codes.

/Gy flag alows packaging individual functions into COMDAT structures. These can be used as a workaround to avoid compile time errors due to multiple definitions of the same symbol. The MSDN documentation states that this just affects build time but not the execution time. They generally recommend using it.

Conclusion:

/Ox disables /Gs, /GF, /Gy. In some cases, these options hurt performance and almost never improve execution speed, compared with /O2. Of course they have benefits but not related to speed.

Visual C++ Compiler Optimization Flags: Difference Between /O2 and /Ot

/O1 and /O2 bundle together a number of options aimed at a larger goal. So /O1 makes a number of code generation choices that favour size; /O2 does the same thing and favours speed.

/O1 includes /Os as well as other options. /O2 includes /Ot as well as other options. Some optimisations are enabled by both /O1 and /O2. And, depending on your program's paging behaviour, /O1 (size) can result in faster speed than /O2 if paging code comes to dominate your perf over instruction execution cost.

A good short summary of the impact of /O1 and /O2 in VC++ 2010 is here

http://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx

and includes links for other versions of VC.

Martyn

In VC++ what is the #pragma equivalent of /O2 compiler option (optimize for speed)

The Microsoft Docs article /O1, /O2 (Minimize Size, Maximize Speed) says for Visual Studio 2017:

The /O1 and /O2 compiler options are a quick way to set several
specific optimization options at once. The /O1 option sets the
individual optimization options that create the smallest code in the
majority of cases. The /O2 option sets the options that create the
fastest code in the majority of cases. The /O2 option is the default
for release builds. This table shows the specific options that are set
by /O1 and /O2:

Option                   Equivalent to
/O1 (Minimize Size) /Og /Os /Oy /Ob2 /GF /Gy
/O2 (Maximize Speed) /Og /Oi /Ot /Oy /Ob2 /GF /Gy

From the Microsoft Docs article /O Options (Optimize Code):

  1. /Og enables global optimizations
  2. /Oi generates intrinsic functions for appropriate function calls.
  3. /Ot (a default setting) tells the compiler to favor optimizations for speed over optimizations for size.
  4. /Oy suppresses the creation of frame pointers on the call stack for quicker function calls.
  5. /Ob2 expands functions marked as inline or __inline and any other function that the compiler chooses

The /G options are:

  1. /GF (Eliminate Duplicate Strings)
  2. /Gy (Enable Function-Level Linking)

The /G options aren't strictly optimizations, so that leaves us with /Og and /Ot, plus #pragma intrinsic (for item 2 in the list), #pragma auto_inline (for item 5 in the list) and possibly #pragma inline_depth. See Microsoft Docs article Optimization Pragmas and Keywords

See also Microsoft Docs article /Ox (Enable Most Speed Optimizations) which indicates the /Ox option is similar to the /O2 option except that it does not turn on /GF nor /Gy. See as well What is the difference between the /Ox and /O2 compiler options?

The Microsoft Docs article Compiler options listed by category has a list of compiler options with links as to what they mean.

What's the difference between -O3 and (-O2 + flags that man gcc says -O3 adds to -O2)?

Man pages can be outdated, but you can find actual lists for O2 and O3.

To get full list (almost, check "update") of -f optimization options actually used, I suggest you use the -fverbose-asm -save-temps (or -fverbose-asm -S) - there is a full list at a top of asm file (*.s).

For gcc-4.6.0 I got x (the difference between O2 and O3) to be:

 -fgcse-after-reload
-finline-functions
-fipa-cp-clone
-fpredictive-commoning
-ftree-loop-distribute-patterns
-ftree-vectorize
-funswitch-loops

Another source of information for your question is the sources of GCC (file gcc/opts.c and possibly gcc/common.opt) as gcc-4.6.0:

/* -O3 optimizations.  */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
/* Inlining of functions reducing size is a good idea with -Os
regardless of them being declared inline. */
{ OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },

I have also checked, does gcc check -On in other files (cscope symbol search for x_optimize).

The only additional usage of n from option -On is saving it value into macro __OPTIMIZE__. So some headers can behave differently for value of this macro equal 2 or 3.

UPDATE: There are questions about it in GCC WIKI:

  • "Is -O1 (-O2,-O3 or -Os) equivalent to individual -foptimization options?"

No. First, individual optimization options (-f*) do not enable optimization, an option -Os or -Ox with x > 0 is required. Second, the -Ox flags enable many optimizations that are not controlled by any individual -f* option. There are no plans to add individual options for controlling all these optimizations.

  • "What specific flags are enabled by -O1 (-O2, -O3 or -Os)?"

Varies by platform and GCC version. You can get GCC to tell you what flags it enables by doing this:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s

Visual C++ compiler optimization

Right click your project, pick "Properties". Now make sure that your current configuration is "Release". In the left part of the window, you should see a tree view with different categories. Optimization options are split amongst the C/C++ and linker entries.

Also, keep in mind, that optimization means the resulting binary is optimized. NOT actually building the binary. The speed gain might be explained due to not having to add debug code etc. but in general, I'd more likely expect building a release version with optimizations to take longer than creating a debug build.



Related Topics



Leave a reply



Submit