C++异常开销

发布于 2024-11-19 14:16:34 字数 681 浏览 8 评论 0原文

为什么嵌入式平台开发人员不断尝试从其 SDK 中删除使用 C++ 异常

例如,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;
 }

的原因是什么?

此行为 据我所知,ARM 编译器完全支持 C++ 异常,但这实际上不可能是问题。还有什么? ARM 平台上的异常使用和展开的开销真的很大,需要花费大量时间来制定此类解决方法吗?

也许还有其他我不知道的事情?

谢谢。

Why do embedded platform developers continuosly attempt to remove usage C++ exceptions from their SDKs?

For example, Bada SDK suggests the following workaround for the exception usage, which looks exceptionally ugly:

 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. 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?

Maybe something else I'm not aware of?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

是你 2024-11-26 14:16:34

只是我的 2 美分...

我专门咨询嵌入式系统,其中大多数都是硬实时和/或安全/生命攸关的系统。它们中的大多数运行在 256K 或更少的闪存/ROM 中 - 换句话说,这些不是具有 1GB+ RAM/闪存和 1GHz+ CPU 的“类 PC”VME 总线系统。它们是深深嵌入的、资源有限的系统。

我想说,至少 75% 使用 C++ 的产品在编译器中禁用异常(即使用禁用异常的编译器开关编译的代码)。我总是问为什么。不管你相信与否,最常见的答案不是运行时或内存开销/成本。

答案通常是这样的:

  • “我们不相信我们知道如何编写异常安全代码”。对他们来说,检查返回值更熟悉、更简单、更安全。
  • “假设您只在特殊情况下抛出异常,那么我们无论如何都会重新启动[通过他们自己的关键错误处理程序例程]”
  • 遗留代码问题(正如贾尔夫所提到的)-他们正在使用多年前开始的代码当他们的编译器不支持异常,或者没有正确或有效地实现它们时

,而且 - 通常对开销有一些模糊的不确定性/恐惧,但几乎总是它是未量化/未分析的,它只是被扔在那里&按面值计算。我可以向您展示报告/文章,其中指出异常的开销为 3%、10%-15% 或 ~30% - 您可以选择。人们倾向于引用表达自己观点的人物。几乎总是,文章已经过时,平台/工具集完全不同,等等。所以正如罗迪所说,你必须在你的平台上衡量自己。

我不一定要捍卫这些立场,我只是向您提供我从许多在嵌入式系统上使用 C++ 的公司那里听到的真实反馈/解释,因为您的问题是“为什么这么多嵌入式开发人员避免异常” ?”

Just my 2 cents...

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. 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 (i.e., code compiled with compiler switches that disable exceptions). I always ask why. Believe it or not, the most common answer is NOT the runtime or memory overhead / cost.

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

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. 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?"

救赎№ 2024-11-26 14:16:34

我可以想到几个可能的原因:

  • 旧版本的编译器不支持异常,因此编写了很多未使用异常的代码(并建立了约定)
  • 异常确实有成本,并且可以占总执行时间的 10-15%(它们也可以实现为几乎不花时间,但会使用相当多的内存,这在嵌入式系统上可能也不是很理想)
  • 嵌入式程序员倾向于有点偏执关于代码大小、性能,尤其是代码复杂性。他们经常担心“高级”功能可能无法与他们的编译器一起正常工作(他们通常也是对的)

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)
  • 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)
剩一世无双 2024-11-26 14:16:34

我认为现在主要是 FUD。

异常在创建具有构造函数/析构函数的对象的块的入口和出口处确实有很小的开销,但在大多数情况下,这实际上不应该相当于一罐bean。

首先测量,其次优化。

但是,抛出异常通常比仅返回布尔标志慢,因此仅针对异常事件抛出异常

在一种情况下,我发现只要抛出异常以供潜在的调试使用,RTL 就会从符号表构建整个可打印堆栈跟踪。正如您可以想象的那样,这不是一件好事。这是几年前的事了,当这个问题曝光时,调试库被匆忙修复。

但是,在我看来,正确使用异常所获得的可靠性远远超过了轻微的性能损失。使用它们,但要小心。

编辑:

@jalf 提出了一些很好的观点,我上面的回答针对的是为什么许多嵌入式开发人员通常仍然贬低异常的相关问题。

但是,如果特定平台 SDK 的开发人员说“不要使用异常”,您可能不得不接受。也许他们的库或编译器中的异常实现存在特定问题 - 或者他们可能担心回调中抛出的异常会导致由于自己的代码中缺乏异常安全而导致问题。

I think it's mostly FUD, these days.

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.

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. 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. 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.

But, if the developer of a particular platform SDK says "don't use exceptions", you'd probably have to go with that. 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.

淡笑忘祈一世凡恋 2024-11-26 14:16:34

这种对异常的态度与性能或编译器支持无关,而与异常增加代码复杂性的想法有关。

据我所知,这个想法几乎总是一个误解,但它似乎有 强大的支持者出于某种不可思议的原因。

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.

攀登最高峰 2024-11-26 14:16:34

其他答案中所支持的与“goto 是邪恶的”相反的观点。我创建这个社区维基是因为我知道这种相反的观点会受到攻击。

任何称职的实时程序员都知道 goto 的这种用法。它是一种广泛使用且广泛接受的错误处理机制。许多硬实时编程环境没有实现< setjmp.h>。从概念上讲,异常只是 setjmplongjmp 的受限版本。那么为什么当底层机制被禁止时还要提供例外呢?

如果始终可以保证所有抛出的异常都在本地处理,则环境可能允许异常。问题是,为什么要这样做?唯一的理由是 goto 总是邪恶的。嗯,他们并不总是邪恶的。

An opinion to the contrary of the "gotos are evil" espoused in the other answers. 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. It is a widely used and widely accepted mechanism for handling errors. Many hard realtime programming environments do not implement < setjmp.h >. Exceptions are conceptually just constrained versions of setjmp and longjmp. 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. Well, they aren't always evil.

策马西风 2024-11-26 14:16:34

现代 C++ 编译器可以将异常的运行时使用量减少到 3% 以下。不过,如果极端的程序员发现它很昂贵,那么他们就会采取这种肮脏的伎俩。

请参阅此处 Bjarne Strourstrup 的页面,为什么使用异常?

Modern C++ compiler can reduce the runtime usage of exception to as less as 3% of overhead. 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 ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文