2010-12-10 3 views
0

Я читал статьи об обработке исключений на C++. Я нашел это topic на StackOverflow. Было простые тесты, я изменил их немного:C++ exceptions, GCC и флаг inline-functions

код 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-функций программы намного быстрее. Я попытался исследовать вывод ассемблера,

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

Я использую GCC v4.5.2 на Intel Core 2 Duo (режим 64 бит).

+0

Почему вы думаете, что '-finline-functions' опасен? gcc должен работать на всех уровнях оптимизации; это не должно идти плохо, когда вы идете на -O3. –

+0

Итак, всегда пользуясь '-O3', я сделал что-то очень не так? –

+0

@Charles: Я знаю, что разработчики ядра Linux не любят оптимизацию псевдонимов gcc, но они включаются при -O2. –

ответ

1

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

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

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

+0

Да, я знаю, что эта программа не равна (я их нашел). Мне было интересно только о такой огромной разнице в времени выполнения между исполняемыми файлами, построенными с и без этого флага оптимизации. Я еще раз исследовал сборку ассемблера и нашел, какая часть была встроена. С другой стороны, я не знал, что прямой вызов функции настолько дорогостоящий на x86 ... – Goofy

Смежные вопросы