Обработка избыточных затрат по стоимости vs setjmp/longjmp
Предполагая, что существует стоимость, связанная с настройкой точки восстановления, можно оптимизировать цикл следующим образом:
while (doContinue) {
try {
doSomeWork ();
}
catch (...) {}
}
В чем-то вроде этого:
while (doContinue) {
try {
do {
doSomeWork ();
} while (doContinue);
break;
} catch (...) {}
}
Но если платформа поддерживает обработку исключений с нулевой стоимостью, эта оптимизация не имеет никакого смысла.
Может ли кто-нибудь указать мне, как обработка исключений с нулевой стоимостью реализована на разных архитектурах, и есть ли способ понять, какие базовые механизмы доступны для генератора компилятора/кода, чтобы решить во время компиляции, оптимизировать ли это это или нет. И может ли компилятор, например, оптимизировать его для вас, если он может предположить, что doSomeWork ()
не имеет побочных эффектов, связанных с циклом?
Ответы
Ответ 1
Метод нулевой стоимости может использоваться только в том случае, если он доступен для используемой цели. Если доступно, он используется большинством компиляторов С++ для производственного качества. В противном случае компилятор будет использовать подход setjmp/longjmp
.
Скорость выполнения setjmp/longjmp
медленнее.
Однако даже при использовании подхода setjmp/longjmp
, использование механизма исключений может привести к большей производительности, чем проверка кода возврата для каждой функции, как в примере с оптимизацией с двумя циклами в вопросе.
Единственный способ узнать, поддерживает ли цель подход с нулевой стоимостью, и если он используется компилятором, - это перевести код С++ в сборку и проанализировать его. Другим решением может быть вызов gnat
с помощью --RTS=zcx
и проверка ошибок, если gnat
доступен. Но это не гарантирует, что он будет использоваться компилятором С++.
В общем случае, если размер программы не является проблемой, и доступны исключения с нулевой стоимостью, использование исключений для обработки неожиданных ситуаций намного лучше, чем проверка кода возврата для каждой функции. В противном случае исключения могут быть использованы для оптимизации кода в определенных случаях.
Используйте, но не злоупотребляйте!
P.S.: Я закончил тем, что написал статью об этом.
Ответ 2
Я думаю, вы слишком оцениваете, что означает "нулевая стоимость". Здесь LLVM doc на нем; основной эффект от него, по-видимому, заключается в том, что код обработки исключений и контекста создается во время компиляции, поэтому во время выполнения нет дополнительных затрат, в то время как выполнение происходит нормально, становясь компромиссом пространства-времени. В вашем примере я считаю, что в два раза больше "посадочных площадок", увеличивая размер и замедляя обработку исключений.