Подтвердить что ты не робот

Накладные расходы на исключение С++

Почему разработчики встроенных платформ постоянно пытаются удалить использование 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, чтобы тратить много времени на такие обходные пути?

Возможно, что-то еще я не знаю?

Спасибо.

4b9b3361

Ответ 1

Я могу думать о нескольких возможных причинах:

  • Старые версии компилятора не поддерживали исключения, поэтому было написано много кода (и были установлены соглашения), где исключения не используются
  • Исключения имеют стоимость, и это может быть до 10-15% от вашего общего времени выполнения (они также могут быть реализованы практически без времени, но вместо этого используют довольно немного памяти, что, вероятно, t очень желательно для встроенных систем)
  • Встраиваемые программисты, как правило, немного параноичны относительно размера кода, производительности и, не в последнюю очередь, сложности кода. Они часто опасаются, что "продвинутые" функции могут работать некорректно с их компилятором (и они часто тоже правы).

Ответ 2

Только мои 2 цента...

Я консультирую исключительно о встроенных системах, большинство из которых жестко критично в режиме реального времени и/или безопасности/жизни. Большинство из них работают на 256 Кбайт флеш-памяти или меньше - другими словами, это не "ПК-подобные" системы шины VME с 1 ГБ + ОЗУ/вспышкой и 1 ГГц + процессор. Это глубоко внедренные системы с ограниченными ресурсами.

Я бы сказал, что не менее 75% продуктов, которые используют С++, отключают исключения в компиляторе (т.е. код, скомпилированный с помощью компиляторов, которые запрещают исключения). Я всегда спрашиваю, почему. Верьте или нет, наиболее распространенным ответом является НЕ время выполнения или накладные расходы/стоимость.

Ответы обычно представляют собой сочетание:

  • "Мы не уверены, что знаем, как писать безопасный код исключения". Для них проверка возвращаемых значений более знакома, менее сложна и безопасна.
  • "Предполагая, что вы исключили исключение только в исключительных случаях, это ситуации, когда мы перезагружаемся в любом случае [через их собственную критическую процедуру обработки ошибок]"
  • Проблемы с устаревшим кодом (как упоминалось в jalf) - они работают с кодом, который начинался много лет назад, когда их компилятор не поддерживал исключения или не выполнял их правильно или эффективно

Кроме того, часто возникает туманная неопределенность/страх перед накладными расходами, но почти всегда она неквалифицированная/непрофильная, она просто отбрасывается и берется за чистую монету. Я могу показать вам отчеты/статьи, в которых говорится, что накладные расходы исключений составляют 3%, 10% -15% или ~ 30% - возьмите свой выбор. Люди склонны цитировать фигуру, которая переводит их собственную точку зрения. Практически всегда, статья устарела, платформа/набор инструментов совершенно другой и т.д., Так как Родди говорит, вы должны измерить себя на своей платформе.

Я не обязательно защищаю любую из этих позиций, я просто даю вам отзывы/объяснения в реальном мире. Я слышал от многих фирм, работающих с С++, на встроенных системах, так как ваш вопрос: "Почему так много встроенных разработчики избегают исключений?"

Ответ 3

Я думаю, что это в основном FUD, в наши дни.

Исключения имеют небольшие накладные расходы при входе и выходе в блоки, которые создают объекты, у которых есть конструкторы/деструкторы, но в большинстве случаев это действительно не должно составлять банку beans.

Сначала измерьте, оптимизируйте второй.

Однако бросание исключения обычно медленнее, чем просто возврат булевского флага, поэтому исключаем исключения только для исключительных событий.

В одном случае я видел, что RTL строит целые печатные трассировки стека из таблиц символов всякий раз, когда было выбрано исключение для потенциального использования отладки. Как вы можете себе представить, это была не хорошая вещь. Это было несколько лет назад, и библиотека отладки была поспешно исправлена, когда это выявилось.

Но, ИМО, надежность, которую вы можете получить от правильного использования исключений, намного перевешивает незначительное наказание. Используйте их, но осторожно.

Изменить:

@jalf делает несколько хороших моментов, и мой ответ выше был нацелен на соответствующий вопрос о том, почему многие встроенные разработчики в целом по-прежнему унижают исключения.

Но если разработчик определенной платформы SDK говорит "не использовать исключения", вам, вероятно, придется пойти на это. Возможно, есть особые проблемы с реализацией исключения в их библиотеке или компиляторе - или, может быть, они обеспокоены исключениями, вызванными обратными вызовами, вызывающими проблемы из-за отсутствия безопасности исключений в их собственном коде.

Ответ 4

В других ответах говорится о противоположности "gotos are evil". Я делаю это сообщество wiki, потому что знаю, что это противоположное мнение будет пылать.

Любой программист в реальном времени, заслуживающий своей соли, знает это использование goto. Это широко используемый и широко распространенный механизм обработки ошибок. Многие сложные среды программирования в реальном времени не реализуют < setjmp.h > . Исключения представляют собой концептуально ограниченные версии setjmp и longjmp. Итак, зачем предоставлять исключения, когда основной механизм запрещен?

Среда может допускать исключения, если всегда можно гарантировать, что все заброшенные исключения могут быть обработаны локально. Вопрос в том, зачем это делать? Единственное оправдание в том, что gotos всегда злые. Ну, они не всегда злые.

Ответ 5

Это отношение к исключениям не имеет ничего общего с поддержкой производительности или компилятора, и все, что связано с идеей о том, что исключения добавляют сложность в код.

Эта идея, насколько я могу судить, почти всегда является заблуждением, но, по-видимому, сильные сторонники по какой-то непостижимой причине.

Ответ 6

Современный С++-компилятор может сократить время использования исключений до 3% от накладных расходов. Тем не менее, если экстремальный программист найдет это дорогим, они прибегают к таким грязным трюкам.

См. здесь страницу Bjarne Strourstrup для Зачем использовать исключения?