Обработка исключений нулевой стоимости против setjmp / longjmp - PullRequest
16 голосов
/ 12 февраля 2011

Предполагая, что с установкой точки восстановления связаны затраты, можно оптимизировать цикл следующим образом:

while (doContinue) {
   try {
     doSomeWork ();
   }
   catch (...) {}
}

На что-то вроде этого:

while (doContinue) {
   try {
      do {
        doSomeWork ();
      } while (doContinue);
      break;
   } catch (...) {}
}

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

Может ли кто-нибудь указать мне, как обработка исключений с нулевой стоимостью реализована на разных архитектурах, и есть ли способ выяснить, какие базовые механизмы доступны для компилятора / генератора кода, чтобы во время компиляции решить, следует ли оптимизировать таким образом или нет. И может ли компилятор, например, оптимизировать его для вас, если он может предположить, что doSomeWork () не имеет побочных эффектов, связанных с циклом?

Ответы [ 2 ]

12 голосов
/ 13 февраля 2011

Подход с нулевой стоимостью можно использовать только в том случае, если он доступен для используемой цели. Если возможно, он используется большинством компиляторов C ++ производственного качества. В противном случае компилятор будет использовать setjmp/longjmp подход.

Скорость выполнения setjmp/longjmp ниже.

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

Единственный способ выяснить, поддерживает ли target подход с нулевой стоимостью и используется ли он компилятором, - это преобразовать код C ++ в сборку и проанализировать его. Другим решением может быть вызов gnat с --RTS=zcx и проверка на наличие ошибок, если gnat доступен. Но это не гарантирует, что он будет использоваться компилятором C ++.

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

Используйте, но не злоупотребляйте!

П.С .: Я закончил тем, что написал статью об этом.

7 голосов
/ 12 февраля 2011

Я думаю, вы переоцениваете значение «нулевой стоимости».Вот документ LLVM на нем;основной эффект этого, по-видимому, заключается в том, что код обработки исключений и контекста создается во время компиляции, поэтому нет дополнительных затрат во время выполнения , в то время как выполнение продолжается обычно , становясьпространственно-временной компромисс.Я полагаю, что в вашем примере будет сгенерировано вдвое больше «посадочных площадок», что увеличит размер и замедлит обработку исключений.

...