Visual Studio C ++编译器选项/O2(最大化速度)等同于
/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy
答案 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次它不会改变任何东西,因为堆栈已经增长第一次 - 如果它需要长大的话。