Visual Studio C ++编译器选项:为什么/ O2定义/ Gs?

时间:2012-03-27 06:36:57

标签: c++ visual-studio

Visual Studio C ++编译器选项/O2(最大化速度)等同于

/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy

为什么/Gs?它如何帮助最大化速度? (请注意,它是/Gs,而不是/GS。)

2 个答案:

答案 0 :(得分:13)

/ Gs会在使用多个页面(通常为4kB)局部变量的函数中插入堆栈探测器。堆栈探测器向操作系统发出信号,告知您将使用大量堆栈空间。如果此探测器到达保护页面,则操作系统知道它将需要为堆栈分配额外的RAM页面来增长。

这是一种优化,因为没有探测器,实际的内存访问将触发RAM分配,并且该功能将停止,直到分配RAM为止。作为功​​能序言的一部分,探测器不会导致失速(至少不会那么严重)。

[编辑] 另一个好处是前面的堆栈探测将分配一次内存。如果您需要16 KB的堆栈空间并依赖按需分配,那么您将有4个页面错误,每个错误会使堆栈增加4 KB。单个探头可以用一个系统调用替换这4个故障。

答案 1 :(得分:2)

/ O2未设置/ Gs,这是文档中的错误。

一些实验(在生成的程序集中很容易看到__chkstk调用)显示:

/ Gs(没有数字)相当于/ Gs0,意味着总是插入__chkstk调用。事实上,MSDN也是如此:

  

如果指定的/ Gs选项没有size参数,则与指定/ Gs0相同,

/ O2 设置/ Gs(又名/ Gs0),“/ O2”和“/ O2 / Gs”之间存在明显差异。虽然它可能会将默认值更改为页面以外的其他内容,但这似乎更可能只是文档错误。

堆栈探针永远不会对性能有好处,它只有在堆栈升级到新的高水位时才能完成,并且在剩余的时间内浪费了。这意味着如果你有一个调用函数100次的循环,那么函数堆栈探测器可能第一次增加堆栈,但是其他99次它不会改变任何东西,因为堆栈已经增长第一次 - 如果它需要长大的话。