C++返回值与异常性能比较

5
我曾经阅读过一篇文章,说现代英特尔处理器具有实现异常的低级硬件,并且大多数编译器都利用它,这样异常比使用变量返回结果状态更快。
这是真的吗?就返回状态/响应状态而言,异常是否比变量更快?在Stack Overflow上阅读有关该主题的内容似乎与此相矛盾。
谢谢。
7个回答

14

请注意,“异常处理程序”一词存在歧义。我认为您会发现,当硬件领域讨论异常时,指的是以下内容:

  1. 硬件中断,也称为信号,其处理程序有时被称为异常处理程序(请参见http://pages.cs.wisc.edu/~smoler/x86text/lect.notes/interrupts.html)。
  2. 机器检查异常,如果硬件出现问题,则会停止计算机的运行(请参见http://en.wikipedia.org/wiki/Machine_Check_Exception)。

这两者都与 C++ 的异常处理设施无关。

作为反例,我至少有一个轶事数据点表明,异常比返回值慢得多:那是在英特尔硬件上使用 gcc 2.95 和非常大的代码集以及非常大的异常表构建的,该异常表在第一次抛出异常时被构建。随后的异常很快,但通常情况下已经造成了损害。诚然,gcc 2.95相当古老,但足以警告您不要对C ++异常处理的速度做出概括,即使是在英特尔硬件上也是如此。


11

我不知道你在哪里看到这个信息,但肯定是错误的。没有硬件设计师会让非常规情况,即定义上不常见的情况比正常情况运行得更快。此外,需要注意的是,根据TIOBE的数据,C语言作为最流行的系统语言之一,甚至不支持异常处理。对于处理某一种语言的异常处理的优化,其实现在编译器中也没有标准化,因此极其不可能处理器会被针对一个语言的异常处理进行优化。

即使异常确实更快,你也不应该在其意图以外的地方使用它们,否则会让全世界的其他程序员感到困惑。


4

不会有比将变量放入寄存器更快的方法。即使有显式的硬件支持,异常仍然需要像访问内存这样的操作。

C ++异常大部分无法以这种方式实现,因为C ++要求堆栈被展开并且对象被销毁。


2
这个答案在技术上是正确的,但极易误导。
问题的核心是异常情况是例外情况。它们通常不会发生。但返回错误代码时并非如此。这总是发生,即使没有错误。在这种情况下,函数仍然必须返回0、true、-1等。
现在这意味着CPU和编译器可以专门优化通过异常失败的函数。但重要的是要意识到他们优化了什么,那就是非故障、非异常的情况——以牺牲异常情况为代价。
一旦我们认识到这一点,我们就可以看看编译器和CPU如何优化这样的情况。一个常见的方法是将异常代码与正常代码分开。结果,该代码通常不会出现在CPU缓存中,因为结果可能包含更有用的代码。事实上,异常代码甚至可能根本没有出现在RAM中,而是留在磁盘上。
另一个支持机制是CPU分支预测器。它会记住导致异常代码的分支通常不会被采取,因此预测下一次它们也不会被采取。编译器甚至可以将其作为提示放入其中。然而,这个提示功能在Intel Pentium 4之后被放弃了;现代CPU足够好地预测分支了。

0
即使它们更快,你也不应该将它们用于除了异常情况以外的任何事情。如果你误用它们,会让你的程序非常难以调试。在gdb中,你可以执行'catch throw',轻松找出你的程序出错并抛出异常的位置,但如果你将异常作为常规处理的一部分抛出,则不能这样做。

0

你的问题有点不清楚,因为你所说的“实现”异常涵盖了三个方面:

  • 进入try块。这个操作可能没有成本,但往往会使throw更加昂贵。在SO上有一个更具体的问题
  • 执行throw。在SO上有一个更具体的问题
  • 展开堆栈以从throw到达其catch,并将错误处理代码(在catch中)加载到CPU缓存中。你应该忽略这个成本,因为如果使用状态码而不是异常,你必须支付这个成本。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接