VS2008 C ++优化器有时会产生较慢的代码吗?

时间:2011-03-03 11:38:23

标签: c++ visual-studio-2008 optimization

previous question之后,我一直在使用我的发布版本中的优化器设置,看看使用编译器优化可以带来哪些好处。到目前为止,我一直在使用/ Ob1(仅内联显式给出内联)和/ Oi(启用内部函数)。我尝试将其更改为include / Ot(赞成快速代码),/ Oy(省略帧指针)和/ Ob2(内联任何合适的),令我惊讶的是,现在需要2小时58分钟的回归套件需要3小时16分钟。我的第一个假设是我自己的内联比编译器更具攻击性,但是从/ Ob2回到/ Ob1只能将事情改进到3h12m。我还在运行更多的测试,但似乎在某些情况下/ Ot(支持快速代码)实际上减慢了速度。该软件是多线程和计算密集型(表面建模,操作和可视化),并且已经基于分析器结果进行了大量手动优化。该程序还处理大量数据,并且经常使用#pragma pack(4)。

所以问题是这样的。对于手动优化的程序,VS2008中的编译器优化是否容易造成更大的损害?换句话说,有没有已知的文档情况,编译器优化会降低性能? (n.b.分析编译器优化代码很痛苦,因此迄今为止对未经优化的代码进行了分析)。

编辑根据Cody Gray和其他建议,我已将/ O2添加到优化设置并重新执行我的测试套件。这导致运行时间为3h01,这与最小优化的运行相当。鉴于(稍微过时)MSDN guide lines on optimization和来自GOZ的帖子,我将检查/ O1以查看我的情况下实际上是否更小。注意当前的EXE文件约为~11mb。我也会尝试将VS2010一起构建,看看票价是多少。

Edit2 使用/ O1时,运行时间为3h00,而11mb exe则小了62k。请注意,这篇文章背后的原因,以及之前的链接,是为了检查启用编译器优化的好处是否超过了分析和调试方面的缺点。在这个具体的例子中,它们看起来并非如此,尽管我承认对所有组合都没有尝试添加任何好处和一些明显降低的性能感到惊讶。 FWIW,根据这个previous thread,我倾向于在设计时进行大部分优化,并主要使用剖析器来检查设计假设,我想我会坚持这种方法。我将在VS2010上进行最后一次启用整个程序优化,并将其保留在那里。

感谢所有反馈!

3 个答案:

答案 0 :(得分:4)

/Ot州的documentation

  

如果您使用/Os/Ot,则还必须指定/Og来优化代码。

因此,您可能希望在测试中始终将/Og/Ot一起传递。

尽管如此,/Ot以牺牲程序大小为代价来支持快速代码,并且可以生成非常大的二进制文件,尤其是在内联繁重的情况下。大型二进制文件很难利用处理器缓存。

答案 1 :(得分:2)

很有可能它试图在循环中内联大型函数或至少大量函数。此时,您将面临导致指令缓存重新加载的风险。这可能会导致大幅放缓。内联并不总是最好的事情(虽然它往往是有帮助的)。如果你有任何包含大量函数调用的大循环,那么最好将循环分成几个循环。这样循环可以保留在指令缓存中,并且您可以获得明显更好的性能。

答案 2 :(得分:2)

众所周知,favour fast code并不总是比favour small code快。编译器启发式并不是无所不知的,它可能会出错。在某些情况下,较小的代码比较快的代码更快。

使用/O2获取最快的代码 - 编译器比您更了解各种设置的交互方式。

等待。您分析了未经优化的代码?那是疯了。编译器优化与手动优化不同 - 它们总是完成,并且没有理由对它们进行分析 - 您可以识别不存在的瓶颈等。如果您想要准确的分析数据,那么首先让编译器做到绝对最好,然后然后分析。

您还可以查看使用Profile Guided Optimization,它将以一些令人印象深刻的方式指导编译器的优化器。