Исключения в C ++, GCC и флаг "inline-functions" - PullRequest
0 голосов
/ 10 декабря 2010

Я читал статьи об обработке исключений в C ++. Я нашел эту тему в StackOverflow. Были простые тесты, я их немного изменил:

код C:

#include <stdio.h>
#include <time.h>

#define BIG 10000000000

long f( long n ) {
    long r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
                return -1;
        }
    }
    return r;
}

int main() { 
    long i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        if ( (z = f(i)) == -1 ) { 
                break;
        }
    }
}

C ++ код:

#include <stdio.h>
#include <time.h>

#define BIG 10000000000

long f( long n ) {
    long r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
                throw -1;
        }
    }
    return r;
}

int main() { 
    long i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        try {
         z += f(i); 
        }
        catch(int tmp) {
                break;
        }

         }
}

Я скомпилировал оба с опцией оптимизации -O2, в результате программа на C оказалась намного быстрее:

gcc -O2 kod.c -o prog_c
time ./prog_c

real 0m8.610s
user 0m8.520s
sys  0m0.010s

g++ -O2 kod.cpp -o prog_cpp
time ./prog_cpp 

real 0m25.460s
user 0m25.260s
sys  0m0.020s

size prog_cpp 
   text    data     bss     dec     hex filename
   2019     592      32    2643     a53 prog_cpp

g++ -O2 kod.cpp -o prog_cpp -finline-functions
time ./prog_cpp 

real 0m8.412s
user 0m8.390s
sys  0m0.000s

size prog_cpp 
   text    data     bss     dec     hex filename
   2019     592      32    2643     a53 prog_cpp

Выходные исполняемые файлы имеют точно такой же размер, но при компиляции с -finline-functions программа работает намного быстрее. Я пытался исследовать вывод ассемблера,

Поскольку -finline-functions включен только на третьем уровне оптимизации GCC, это как-то опасно, поэтому, пожалуйста, скажите, почему я не должен использоваться в производительном коде?

Я использую GCC v4.5.2 на Intel Core 2 Duo (64-разрядный режим).

1 Ответ

1 голос
/ 10 декабря 2010

Эти программы не эквивалентны. В версии C вы возвращаете своего дозорного, но в C ++ вы его бросаете. Исключение не обязательно возвращается вызывающей стороне, и поэтому некоторые дополнительные механизмы размещаются как на узлах вызова, так и в вызываемой функции для организации развертывания стека. Самая близкая вещь в C к исключению C ++ - longjmp.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...