C ++异常开销

时间:2011-07-13 11:08:39

标签: c++ exception embedded arm overhead

为什么嵌入式平台开发人员会继续尝试从C++ exceptions中删除使用SDKs

例如,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++ exceptions,这实际上不是问题。还有什么? ARM平台上的异常使用和展开的开销是否真的 BIG 花费大量时间进行此类变通办法?

也许其他我不知道的东西?

谢谢。

6 个答案:

答案 0 :(得分:48)

只是我的2美分......

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

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

答案通常是以下几种:

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

此外 - 通常有一些模糊的不确定性/担心开销,但几乎总是它没有量化/未被发现,它只是被抛出那里&从表面上看。我可以向您展示报告/文章,说明例外的开销是3%,10%-15%或~30% - 请您选择。人们倾向于引用转发自己观点的数字。几乎总是,文章已经过时,平台/工具集完全不同等等,正如罗迪所说,你必须在自己的平台上衡量自己。

我不一定会为这些职位辩护,我只是向你提供我从许多在嵌入式系统上使用C ++的公司获得的真实反馈/解释,因为你的问题是“为什么这么多嵌入式系统开发人员避免例外?“

答案 1 :(得分:19)

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

  • 旧版本的编译器不支持异常,因此编写了大量代码(并且已经建立了约定),其中不使用异常
  • 例外确实有成本,它可以占总执行时间的10-15%(它们也可以实现几乎没有时间,但使用相当多的内存,这可能不是'在嵌入式系统中非常需要))
  • 嵌入式程序员往往对代码大小,性能以及代码复杂性有点偏执。他们经常担心“高级”功能可能无法正常使用他们的编译器(而且它们通常也是正确的)

答案 2 :(得分:7)

我认为这些日子主要是FUD。

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

先测量,优化秒。

但是,抛出异常通常比返回布尔标志要慢,所以仅为异常事件抛出异常

在一个案例中,我看到RTL正在构建来自符号表的整个可打印堆栈跟踪,只要抛出异常以供潜在的调试使用。你可以想象,这是 Not a Good Thing 。这是几年前的事情,当调试时,调试库已经匆忙修复。

但是,IMO,正确使用异常可以获得的可靠性远远超过轻微的性能损失。使用它们,但要小心。

修改:

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

但是,如果特定平台SDK的开发人员说“不使用例外”,那么您可能不得不这样做。也许他们的库或编译器中的异常实现存在特殊问题 - 或者他们担心回调中引发的异常会导致由于他们自己的代码中缺少异常安全而导致的问题。

答案 3 :(得分:5)

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

据我所知,这个想法几乎总是一种误解,但似乎有一些不可思议的原因powerful proponents

答案 4 :(得分:5)

在其他答案中,有人认为“有人是邪恶的”是相反的。我正在制作这个社区维基,因为我知道这种相反的意见会受到抨击。

任何值得他们盐的实时程序员都知道goto的使用。它是一种广泛使用且被广泛接受的处理错误的机制。许多硬实时编程环境没有实现< setjmp.h>。例外是setjmplongjmp的概念上受限制的版本。那么为什么在禁用基础机制时提供异常呢?

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

答案 5 :(得分:4)

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

请参阅Bjarne Strourstrup的页面,Why use Exceptions ?