noexcept,堆叠展开和性能 [英] noexcept, stack unwinding and performance

查看:209
本文介绍了noexcept,堆叠展开和性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下来自Scott Meyers的草案 C ++ 11书说(第2页,第7-21行)

The following draft from Scott Meyers new C++11 book says(page 2, lines 7-21)


展开调用堆栈和可能展开之间的区别有
对代码生成产生了惊人的巨大影响。在noexcept函数中,优化器
无需将运行时堆栈保持在可解除状态,如果
异常传播出函数,也不必确保noexcept
函数中的对象被销毁在反向顺序的构造中应该有一个例外
离开函数。结果是更多的机会优化,不仅
在一个noexcept函数的身体,而且在功能是
调用的站点。这种灵活性仅适用于noexcept功能。
throw()异常规范的功能缺少它,根本没有异常规范的功能。

The difference between unwinding the call stack and possibly unwinding it has a surprisingly large impact on code generation. In a noexcept function, optimizers need not keep the runtime stack in an unwindable state if an exception would propagate out of the function, nor must they ensure that objects in a noexcept function are destroyed in the inverse order of construction should an exception leave the function. The result is more opportunities for optimization, not only within the body of a noexcept function, but also at sites where the function is called. Such flexibility is present only for noexcept functions. Functions with "throw()" exception specifications lack it, as do functions with no exception specification at all.

对比, 5.4 部分rel = noreferrer>C ++性能技术报告描述了实现异常处理的代码和表方式。特别地,当没有异常被抛出并且只有空间开销时,table方法被显示为没有时间开销。

In contrast, section 5.4 of "Technical Report on C++ Performance" describes the "code" and "table" ways of implementing exception handling. In particular, the "table" method is shown to have no time overhead when no exceptions are thrown and only has a space overhead.

我的问题是这样 - 哪些优化是斯迈特·迈尔斯谈论何时谈论展开与可能展开?为什么这些优化不适用于 throw()?他的评论仅适用于2006年TR中提到的代码方法。

My question is this - what optimizations is Scott Meyers talking about when he talks of unwinding vs possibly unwinding? Why don't these optimizations apply for throw()? Do his comments apply only to the "code" method mentioned in the 2006 TR?

推荐答案

有否开销,开销您可以通过不同的方式来考虑编译器:

There's "no" overhead and then there's no overhead. You can think of the compiler in different ways:


  • 它生成执行某些操作的程序。

  • 它生成一个满足某些约束的程序。

TR表示在没有操作需要行动的情况下,只要不发生投掷就被采取。非特殊的执行路径直截了当。

The TR says there's no overhead in the table-driven appraoch because no action needs to be taken as long as a throw doesn't occur. The non-exceptional execution path goes straight forward.

但是,为了使这些表工作,非特殊代码仍然需要额外的约束。在任何异常可能导致其破坏之前,每个对象都需要被完全初始化,从而限制了潜在的投掷调用中指令的重新排序(例如从内联构造函数)。同样,在任何可能的后续异常之前,一个对象必须被完全破坏。

However, to make the tables work, the non-exceptional code still needs additional constraints. Each object needs to be fully initialized before any exception could lead to its destruction, limiting the reordering of instructions (e.g. from an inlined constructor) across potentially throwing calls. Likewise, an object must be completely destroyed before any possible subsequent exception.

基于表的展开只适用于遵循ABI调用约定的功能,具有堆栈框架。没有异常的可能性,编译器可能会自由地忽略ABI并省略框架。

Table-based unwinding only works with functions following the ABI calling conventions, with stack frames. Without the possibility of an exception, the compiler may have been free to ignore the ABI and omit the frame.

空间开销,又称为膨胀,以表格和单独的形式特殊的代码路径可能不会影响执行时间,但它仍然可以影响下载程序所需的时间并将其加载到RAM中。

Space overhead, a.k.a. bloat, in the form of tables and separate exceptional code paths, might not affect execution time, but it can still affect time taken to download the program and load it into RAM.

这些都是相对的,但 noexcept 削减编译器一些松动。

It's all relative, but noexcept cuts the compiler some slack.

这篇关于noexcept,堆叠展开和性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆