【发布时间】:2010-07-04 05:04:02
【问题描述】:
我在某处读到现代英特尔处理器具有用于实现异常的低级硬件,并且大多数编译器都利用它,因此异常比使用变量返回结果状态更快。
这是真的吗?就返回状态/响应状态而言,异常是否比变量快?阅读有关该主题的堆栈溢出似乎与此相矛盾。
谢谢
【问题讨论】:
标签: c++ performance exception
我在某处读到现代英特尔处理器具有用于实现异常的低级硬件,并且大多数编译器都利用它,因此异常比使用变量返回结果状态更快。
这是真的吗?就返回状态/响应状态而言,异常是否比变量快?阅读有关该主题的堆栈溢出似乎与此相矛盾。
谢谢
【问题讨论】:
标签: c++ performance exception
请注意,术语“异常处理程序”有歧义。我相信您会发现,硬件人员在谈论异常时的含义如下:
这些都与 C++ 的异常处理工具无关。
作为一个反例,我至少有一个轶事数据点,其中异常比返回代码慢得多:这在 Intel 硬件上还可以,但是使用 gcc 2.95 和一组非常大的异常表,即是在第一次抛出异常时构造的。随后的例外情况很快,但到那时通常会造成损害。诚然,gcc 2.95 相当古老,但它应该足以提醒您不要对 C++ 异常处理的速度进行概括,即使在 Intel 硬件上也是如此。
【讨论】:
我不知道你是从哪里读到的,但这肯定是不正确的。没有任何硬件设计人员会在异常情况下(根据定义不常见)比正常情况下工作得更快。还要记住,C,根据TIOBE 是最流行的系统语言,甚至不支持异常。处理器似乎极不可能针对 ONE 语言的异常处理进行优化,其实现在编译器中甚至都没有标准化。
即使以某种方式异常更快,您仍然不应该在预期目的之外使用它们,以免混淆世界上所有其他程序员。
【讨论】:
没有。没有什么比将变量插入寄存器更快的了。即使有明确的硬件支持,异常仍然需要诸如内存访问之类的东西。
C++ 异常在大多数情况下无法以这种方式实现,因为 C++ 要求展开堆栈并销毁对象。
【讨论】:
答案在技术上是正确的,但高度具有误导性。
问题的核心是观察到异常是异常的。它们通常不会发生。当您返回错误代码时,情况并非如此。即使没有错误,这种情况总是会发生。在这种情况下,函数仍然必须返回 0、true、-1 或 ...
现在这意味着 CPU 和编译器可以专门优化因异常而失败的函数。但重要的是要实现他们优化的,这就是非失败、非异常情况 - 以异常情况为代价。
一旦我们意识到这一点,我们就可以看看编译器和 CPU 如何优化这种情况。一种常见的方法是将异常代码与正常代码分开。因此,该代码通常不会出现在 CPU 缓存中,从而可以包含更多有用的代码。事实上,异常代码可能根本不会出现在 RAM 中,而是留在磁盘上。
另一个支持机制是 CPU 分支预测器。它会记住导致异常代码的分支通常不被采用,因此预测下次它们也不会被采用。编译器甚至可以把它作为提示。然而,这个提示功能在 Intel Pentium 4 之后就被放弃了;现代 CPU 可以很好地预测分支。
【讨论】:
即使它们更快,您也不应该将它们用于除特殊情况之外的任何用途。如果你滥用它们,你的程序会更难调试。在 gdb 中,您可以执行“catch throw”并轻松找出程序出错的地方并抛出异常,但如果您将异常作为常规处理的一部分抛出,则不会。
【讨论】:
你的问题有点不清楚,因为你的意思是实现异常包括三件事:
try 块。这可以有没有成本,但往往会使throw更贵。有a more specific question about this on SO。throw。有a more specific question about this on SO。throw 获取到它的catch,并将错误处理代码(在catch 中)加载到CPU 缓存中。您应该忽略此费用,因为如果使用状态代码而不是异常,您必须支付此费用。【讨论】: