简体   繁体   English

C++ 异常开销

[英]C++ exception overhead

Why do embedded platform developers continuosly attempt to remove usage C++ exceptions from their SDKs ?为什么嵌入式平台开发人员不断尝试从他们的SDKs中删除使用C++ exceptions

For example, Bada SDK suggests the following workaround for the exception usage, which looks exceptionally ugly:例如, Bada SDK为异常使用建议了以下变通方法,看起来异常难看:

 result
 MyApp::InitTimer()
 {
    result r = E_SUCCESS;

    _pTimer = new Timer;

    r = _pTimer->Construct(*this);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    _pTimer->Start(1000);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    return r;
 CATCH:
     return r;
 }

What are the reasons for this behavior?这种行为的原因是什么?

As far as I know, ARM compilers fully support C++ exceptions and this couldn't actually be the matter.据我所知, ARM编译器完全支持C++ exceptions ,这实际上不是问题。 What else?还有什么? Is the overhead of the exception usage and unwindings on ARM platforms really that BIG to spend a lot time making such workarounds? ARM平台上的异常使用和展开的开销真的要花很多时间做这样的变通方法吗?

Maybe something else I'm not aware of?也许还有其他我不知道的东西?

Thank you.谢谢你。

Just my 2 cents...只是我的2美分...

I consult exclusively on embedded systems, most of them hard real-time and/or safety/life critical.我专门咨询嵌入式系统,其中大多数是硬实时和/或安全/生命攸关的。 Most of them run in 256K of flash/ROM or less - in other words, these are not "PC-like" VME bus systems with 1GB+ of RAM/flash and a 1GHz+ CPU.它们中的大多数运行在 256K 或更少的闪存/ROM 中 - 换句话说,这些不是具有 1GB+ RAM/闪存和 1GHz+ CPU 的“类似 PC”的 VME 总线系统。 They are deeply embedded, somewhat resource-constrained systems.它们是深度嵌入、资源有限的系统。

I would say at least 75% of the products which use C++ disable exceptions at the compiler (ie, code compiled with compiler switches that disable exceptions).我想说至少 75% 的使用 C++ 的产品在编译器中禁用异常(即,使用禁用异常的编译器开关编译的代码)。 I always ask why.我总是问为什么。 Believe it or not, the most common answer is NOT the runtime or memory overhead / cost.信不信由你,最常见的答案不是运行时或 memory 开销/成本。

The answers are usually some mix of:答案通常是以下几种:

  • "We're not confident that we know how to write exception safe code". “我们不确定我们知道如何编写异常安全代码”。 To them, checking return values is more familiar, less complex, safer.对他们来说,检查返回值更熟悉、更简单、更安全。
  • "Assuming you only throw an exception in exceptional cases, these are situations where we reboot anyway [via their own critical error handler routine]" “假设你只在特殊情况下抛出异常,这些情况下我们无论如何都要重启 [通过他们自己的严重错误处理程序例程]”
  • Legacy code issues (as jalf had mentioned) - they're working with code that started out many years ago when their compiler didn't support exceptions, or didn't implement them correctly or efficiently遗留代码问题(正如 jalf 所提到的) - 他们正在使用多年前开始的代码,当时他们的编译器不支持异常,或者没有正确或有效地实现它们

Also - there is often some nebulous uncertainty/fear about overhead, but almost always it's unquantified / unprofiled, it's just kind of thrown out there & taken at face value.此外 - 经常有一些关于开销的模糊不确定性/恐惧,但几乎总是它是未量化/未分析的,它只是一种被扔在那里并按面值计算。 I can show you reports / articles that state that the overhead of exceptions is 3%, 10%-15%, or ~30% - take your pick.我可以向您展示 state 的报告/文章,异常开销为 3%、10%-15% 或 ~30% - 任您选择。 People tend to quote the figure that forwards their own viewpoint.人们倾向于引用代表自己观点的人物。 Almost always, the article is outdated, the platform/toolset is completely different, etc. so as Roddy says, you must measure yourself on your platform.几乎总是,文章已经过时,平台/工具集完全不同,等等。正如罗迪所说,你必须在你的平台上衡量自己。

I'm not necessarily defending any of these positions, I'm just giving you real-world feedback / explanations I've heard from many firms working with C++ on embedded systems, since your question is "why do so many embedded developers avoid exceptions?"我不一定要为这些立场辩护,我只是给你真实的反馈/解释,我从许多与 C++ 在嵌入式系统上合作的公司那里听到,因为你的问题是“为什么这么多嵌入式开发人员避免例外?”

I can think of a couple of possible reasons:我能想到几个可能的原因:

  • Older versions of the compiler didn't support exceptions, so a lot of code has been written (and conventions have been established) where exceptions are not used旧版本的编译器不支持异常,因此编写了很多代码(并建立了约定),其中不使用异常
  • Exceptions do have a cost, and it can be as much as 10-15% of your total execution time (they can also be implemented to take virtually no time, but use quite a bit of memory instead, which probably isn't very desirable on embedded systems either)异常确实是有代价的,它可能占总执行时间的 10-15%(它们也可以实现为几乎不花时间,但使用相当多的 memory 代替,这可能不是很理想在嵌入式系统上)
  • Embedded programmers tend to be a bit paranoid about code size, performance and, not least, code complexity.嵌入式程序员往往对代码大小、性能,尤其是代码复杂性有点偏执。 They often worry that "advanced" features may not work correctly with their compiler (and they're often right too)他们经常担心“高级”功能可能无法在他们的编译器中正常工作(而且他们通常也是正确的)

I think it's mostly FUD, these days.我认为这主要是 FUD,这些天。

Exceptions do have a small overhead at the entry and exit to blocks that create objects that have constructors/destructors, but that really shouldn't amount to a can of beans in most cases.异常确实在创建具有构造函数/析构函数的对象的块的入口和出口处有少量开销,但在大多数情况下,这实际上不应该相当于一罐豆子。

Measure first, Optimize second.先测量,再优化。

However, throwing an exception is usually slower than just returning a boolean flag, so throw exceptions for exceptional events only .但是,抛出异常通常比仅返回 boolean 标志要慢,因此仅针对异常事件抛出异常

In one case, I saw that the RTL was constructing entire printable stack traces from symbol tables whenever an exception was thrown for potential debugging use.在一种情况下,我看到 RTL 正在从符号表构造整个可打印的堆栈跟踪,只要抛出异常以供潜在的调试使用。 As you can imagine, this was Not a Good Thing .可以想象,这不是一件好事 This was a few years back and the debugging library was hastily fixed when this came to light.这是几年前的事了,当这个问题曝光时,调试库被匆忙修复。

But, IMO, the reliability that you can gain from correct use of exceptions far outweighs the minor performance penalty.但是,IMO,您从正确使用异常中获得的可靠性远远超过了轻微的性能损失。 Use them, but carefully.使用它们,但要小心。

Edit:编辑:

@jalf makes some good points, and my answer above was targeted at the related question of why many embedded developers in general still disparage exceptions. @jalf 提出了一些很好的观点,我上面的回答针对的是为什么许多嵌入式开发人员通常仍然贬低例外的相关问题。

But, if the developer of a particular platform SDK says " don't use exceptions ", you'd probably have to go with that.但是,如果特定平台 SDK 的开发人员说“不要使用异常”,那么您可能不得不使用 go。 Maybe there are particular issues with the exception implementation in their library or compiler - or maybe they are concerned about exceptions thrown in callbacks causing issues due to a lack of exception safety in their own code.也许他们的库或编译器中的异常实现存在特殊问题 - 或者他们担心回调中抛出的异常会由于他们自己的代码中缺乏异常安全性而导致问题。

This attitude towards exceptions has nothing to do whatsoever with performance or compiler support, and everything to do with an idea that exceptions add complexity to the code .这种对异常的态度与性能或编译器支持无关,而是与异常增加代码复杂性的想法有关。

This idea, as far as I can tell, is nearly always a misconception, but it seems to have powerful proponents for some inconceivable reason.据我所知,这个想法几乎总是一种误解,但由于某些不可思议的原因,它似乎有 强大的支持者

An opinion to the contrary of the "gotos are evil" espoused in the other answers.与其他答案所支持的“gotos are evil”相反的观点。 I'm making this community wiki because I know that this contrary opinion will be flamed.我正在制作这个社区维基,因为我知道这种相反的观点会被激怒。

Any realtime programmer worth their salt knows this use of goto .任何称职的实时程序员都知道goto的这种用法。 It is a widely used and widely accepted mechanism for handling errors.它是一种广泛使用且被广泛接受的错误处理机制。 Many hard realtime programming environments do not implement < setjmp.h >.许多硬实时编程环境没有实现<setjmp.h>。 Exceptions are conceptually just constrained versions of setjmp and longjmp .例外在概念上只是setjmplongjmp的受限版本。 So why provide exceptions when the underlying mechanism is banned?那么,当底层机制被禁止时,为什么要提供异常呢?

An environment might allow exceptions if all thrown exceptions can always be guaranteed to be handled locally.如果始终可以保证在本地处理所有抛出的异常,则环境可能允许异常。 The question is, why do this?问题是,为什么要这样做? The only justification is that gotos are always evil.唯一的理由是 gotos 总是邪恶的。 Well, they aren't always evil.好吧,他们并不总是邪恶的。

Modern C++ compiler can reduce the runtime usage of exception to as less as 3% of overhead.现代 C++ 编译器可以将异常的运行时使用率降低到低至 3% 的开销。 Still if the extreme programmer find it expensive then they would have resorted to such dirty tricks.尽管如此,如果极端程序员发现它很昂贵,那么他们就会诉诸这种肮脏的伎俩。

See here Bjarne Strourstrup's page for, Why use Exceptions?请参阅此处 Bjarne Strourstrup 的页面,了解为什么使用异常?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM