【问题标题】:Performance when exceptions are not thrown (C++)不引发异常时的性能 (C++)
【发布时间】:2010-09-19 08:11:40
【问题描述】:

我已经阅读了很多关于 C++ 异常的内容以及我所看到的,特别是异常性能是一个很难的话题。我什至试图深入了解 g++ 的底层,看看异常在汇编中是如何表示的。

我是一名 C 程序员,因为我更喜欢低级语言。前段时间我决定使用 C++ 而不是 C,因为它可以让我的生活更轻松(类而不是结构、模板等)。

回到我的问题,因为我看到异常确实会产生开销只有在它们发生时才会萌芽,因为它需要一长串的跳转和比较指令才能找到适当的异常处理程序。在正常的程序执行中(没有错误)异常开销等于正常的返回码检查。我说的对吗?

【问题讨论】:

  • 感谢标题中的“再次”后缀。
  • 我认为答案是特定于编译器的
  • 如果您想了解性能影响,衡量它
  • 如果我没记错的话,现代平台上的现代实现对于无异常路径的开销为零。您可能想查看可以从open-std.org/jtc1/sc22/wg21 下载的“C++ 性能报告”
  • 在许多情况下,类似 C 的手动错误检查变得如此复杂,以至于程序员的开销甚至超过了带有异常的普通编译器。

标签: c++ exception


【解决方案1】:

请看我对类似问题here的详细回复。

异常处理开销因平台而异,取决于操作系统、编译器和运行的 CPU 架构。

对于 Visual Studio、Windows 和 x86,即使不引发异常也会产生成本。编译器生成额外的代码来跟踪当前的“范围”,该范围稍后用于确定要调用的析构函数以及从哪里开始搜索异常过滤器和处理程序。范围更改由try 块和使用析构函数创建对象触发。

对于 Visual Studio、Windows 和 x86-64,当不引发异常时,成本基本上为零。 x86-64 ABI 在异常处理方面的协议比 x86 严格得多,而且操作系统做了很多繁重的工作,因此程序本身不需要跟踪太多信息来处理异常。

当异常发生时,成本很高,这就是为什么它们应该只在真正异常的情况下发生。在 x86-64 上处理异常比在 x86 上更昂贵,因为该架构针对不发生异常的更常见情况进行了优化。

【讨论】:

  • 我知道已经 3 年了,但是 Linux x86-64 上的开销也很少吗?
  • @JAKE6459 我无法确切回答,但 x86-64 优于 x86 的好处之一是支持异常的方式,我确信 Linux 会利用这一点。与往常一样,如果您真的需要了解,请分析您的代码。如果您在 Linux 上使用 C/C++,请查看 gprof
  • 你能诚实地说,在关闭异常的情况下编译的代码并没有明显更快吗?
【解决方案2】:

以下是对实际未抛出异常时的异常处理成本的详细回顾:

http://www.nwcpp.org/old/Meetings/2006/10.html

一般来说,在每个使用异常处理的函数中(有 try/catch 块或带有析构函数的自动对象) - 编译器会生成一些额外的 prolog/epilog 代码来处理异常注册记录。

另外,在构造和销毁每个自动对象之后 - 添加了更多的汇编程序命令(调整异常注册记录)。

此外,一些优化可能会被禁用。当您在所谓的“异步”异常处理模型中工作时尤其如此。

【讨论】:

猜你喜欢
  • 2014-12-05
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 2020-07-14
  • 1970-01-01
相关资源
最近更新 更多