visual-studio “优化代码”选项在 Visual Studio 中的真正作用是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/113866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 09:38:05  来源:igfitidea点击:

What does "Optimize Code" option really do in Visual Studio?

visual-studiooptimization

提问by spinodal

Name of the option tells something but what Visual Studio/compiler really do and what are the real consequences?

选项的名称说明了一些事情,但 Visual Studio/编译器真正做了什么以及真正的后果是什么?

Edit: If you search google you can find this address, but that is not really I am looking for. I wonder the real things happening. For example why do the loops get less time, etc.

编辑:如果你搜索谷歌,你可以找到这个地址,但这并不是我真正要找的。我想知道真实发生的事情。例如,为什么循环获得的时间更少,等等。

采纳答案by Suma

Without optimizations the compiler produces very dumb code - each command is compiled in a very straightforward manner, so that it does the intended thing. The Debug builds have optimizations disabled by default, because without the optimizations the produced executable matches the source code in a straightforward manner.

如果没有优化,编译器会生成非常愚蠢的代码 - 每个命令都以非常直接的方式编译,以便它执行预期的操作。默认情况下,调试版本禁用优化,因为如果没有优化,生成的可执行文件会以直接的方式匹配源代码。

Variables kept in registers

保存在寄存器中的变量

Once you turn on the optimizations, the compiler applies many different techniques to make the code run faster while still doing the same thing. The most obvious difference between optimized and unoptimized builds in Visual C++ is the fact the variable values are kept in registers as long as possible in optimized builds, while without optimizations they are always stored into the memory. This affects not only the code speed, but it also affects debugging. As a result of this optimization the debugger cannot reliably obtain a variable value as you are stepping through the code.

一旦您打开优化,编译器就会应用许多不同的技术来使代码运行得更快,同时仍然做同样的事情。Visual C++ 中优化和未优化构建之间最明显的区别是变量值在优化构建中尽可能长时间地保存在寄存器中,而在没有优化的情况下,它们总是存储在内存中。这不仅会影响代码速度,还会影响调试。作为这种优化的结果,调试器无法在您单步调试代码时可靠地获得变量值。

Other optimizations

其他优化

There are multiple other optimizations applied by the compiler, as described in /O Options (Optimize Code) MSDN docs. For a general description of various optimizations techniques see Wikipedia Compiler Optimization article.

编译器应用了多种其他优化,如/O 选项(优化代码)MSDN 文档 中所述。有关各种优化技术的一般描述,请参阅Wikipedia Compiler Optimization 文章

回答by reva

From Paul Vick'sblog:

来自保罗维克的博客:

  • It removes any NOP instructions that we would otherwise emit to assist in debugging. When optimizations are off (and debugging information is turned on), the compiler will emit NOP instructions for lines that don't have any actual IL associated with them but which you might want to put a breakpoint on. The most common example of something like this would be the “End If“ of an “If” statement - there's no actual IL emitted for an End If, so we don't emit a NOP the debugger won't let you set a breakpoint on it. Turning on optimizations forces the compiler not to emit the NOPs.

  • We do a simple basic block analysis of the generated IL to remove any dead code blocks. That is, we break apart each method into blocks of IL separated by branch instructions. By doing a quick analysis of how the blocks interrelate, we can identify any blocks that have no branches into them. Thus, we can figure out code blocks that will never be executed and can be omitted, making the assembly slightly smaller. We also do some minor branch optimizations at this point as well - for example, if you GoTo another GoTo statement, we just optimize the first GoTo to jump to the second GoTo's target.

  • We emit a DebuggableAttribute with IsJITOptimizerDisabled set to False. Basically, this allows the run-time JIT to optimize the code how it sees fit, including reordering and inlining code. This will produce more efficient and smaller code, but it means that trying to debug the code can be very challenging (as anyone who's tried it will tell you). The actual list of what the JIT optimizations are is something that I don't know - maybe someone like Chris Brumme will chime in at some point on this. The long and the short of it is that the optimization switch enables optimizations that might make setting breakpoints and stepping through your code harder.

  • 它删除了我们本来会发出以帮助调试的任何 NOP 指令。当优化关闭(并打开调试信息)时,编译器将为没有任何实际 IL 关联的行发出 NOP 指令,但您可能希望在这些行上设置断点。像这样的最常见的例子是“If”语句的“End If”——没有为 End If 发出实际的 IL,所以我们不发出 NOP,调试器不会让你设置断点在上面。打开优化会强制编译器不发出 NOP。

  • 我们对生成的 IL 进行简单的基本块分析,以删除任何死代码块。也就是说,我们将每个方法分解为由分支指令分隔的 IL 块。通过快速分析块之间的相互关系,我们可以识别没有分支的块。因此,我们可以找出永远不会执行和可以省略的代码块,使程序集稍微小一些。在这一点上我们也做了一些小的分支优化——例如,如果你转到另一个 GoTo 语句,我们只是优化第一个 GoTo 以跳转到第二个 GoTo 的目标。

  • 我们发出一个 DebuggableAttribute,并将 IsJITOptimizerDisabled 设置为 False。基本上,这允许运行时 JIT 以它认为合适的方式优化代码,包括重新排序和内联代码。这将产生更高效和更小的代码,但这意味着尝试调试代码可能非常具有挑战性(任何尝试过它的人都会告诉你)。JIT 优化的实际列表是我不知道的——也许像 Chris Brumme 这样的人会在某个时候加入这个。总而言之,优化开关启用的优化可能会使设置断点和单步执行代码变得更加困难。

回答by JesperE

The short answer is: use -Ox and let the compiler do its job.

简短的回答是:使用 -Ox 并让编译器完成它的工作。

The long answer: the effect of different kind of optimizations is impossible to predict accurately. Sometimes optimizing for fast code will actually yield smaller code than when optimizing for size. If you really want to get the last 0.01% of performance (speedwise or sizewise), you have to benchmark different combination of options.

答案很长:无法准确预测不同类型优化的效果。有时优化快速代码实际上会产生比优化大小更小的代码。如果您真的想获得最后 0.01% 的性能(速度或尺寸),则必须对不同的选项组合进行基准测试。

Also, recent versions of Visual Studio have options for more advanced optimizations such as link-time optimization and profile-guided optimization.

此外,最新版本的 Visual Studio 具有用于更高级优化的选项,例如链接时优化和配置文件引导优化。