Joh*_*åde 16 c++ visual-studio
Visual Studio C++编译器选项/ O2(最大化速度)相当于
/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy
Run Code Online (Sandbox Code Playgroud)
MSa*_*ers 13
/ Gs将在使用多个页面(通常为4kB)局部变量的函数中插入堆栈探测器.堆栈探测器向操作系统发出信号,告知您将使用大量堆栈空间.如果此探测器到达保护页面,则操作系统知道它将需要为堆栈分配额外的RAM页面来增长.
这是一种优化,因为没有探测器,实际的存储器访问将触发RAM分配,并且该功能将停止,直到分配RAM为止.作为函数序言的一部分,探针不会导致失速(至少不会那么严重).
[edit]另一个好处是前面的堆栈探测将分配一次内存.如果您需要16 KB的堆栈空间并依赖按需分配,那么您将有4个页面错误,每个错误会使堆栈增加4 KB.单个探头可以用一个系统调用替换这4个故障.
/O2 没有设置 /Gs,这是文档中的错误。
一些实验(很容易在生成的程序集中看到 __chkstk 调用)表明:
/Gs(没有数字)相当于 /Gs0,意味着始终插入 __chkstk 调用。事实上,MSDN 也这么说:
如果指定 /Gs 选项时没有指定大小参数,则与指定 /Gs0 相同,
/O2 不设置/Gs(又名 /Gs0),“/O2”和“/O2 /Gs”之间有明显的区别。尽管它有可能将默认值更改为页面以外的其他内容,但这似乎更有可能只是一个文档错误。
堆栈探针永远不会有利于性能,它只在堆栈前进到新的高水位线时才起作用,并且在其余时间中被浪费循环。这意味着,如果您有一个调用函数 100 次的循环,则该函数堆栈探测可能会在第一次增加堆栈,但其他 99 次它不会改变任何内容,因为堆栈已经在第一次增加 - 如果需要的话完全成长。