2010-12-10 10 views
0

C++で例外処理に関する記事を読んでいました。私はStackOverflowでこれを見つけたtopic。簡単なテストにあった、私は彼らを少し変更:C++例外、GCCと "インライン関数"フラグ

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; 
     } 

     } 
} 

私は結果Cプログラムでは、-O2最適化オプションの両方をコンパイルしましたはるかに高速:

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-functionsはGCCの3番目のレベルでしか有効になっていないので、何とか危険です。なぜ、私は生産的なコードで使用すべきではないのか教えてください。

Intel Core 2 Duo(64ビットモード)でGCC v4.5.2を使用します。

+0

なぜ '-finline-functions'が危険だと思いますか? gccはすべての最適化レベルで動作するはずです。あなたが-O3に行くときに悪くなるはずがありません。 –

+0

それで、常に '-O3'を使用していたのですが、私は何か非常に間違っていましたか? –

+0

@Charles:Linuxカーネルの開発者はgccの厳密なエイリアス最適化を気にしませんが、それは-O2でオンになります。 –

答えて

1

これらのプログラムは同等ではありません。 Cバージョンでは、あなたはセンチネルを返しますが、C++ではそれを投げます。例外は必ずしも呼び出し元に返されるわけではないので、いくつかの追加の機械はコールサイトと呼び出された関数の両方に配置され、スタックの展開を手配します。 C++の例外に最も近いのはlongjmpです。

コンパイラがインライン最適化を実行することを決定した場合、呼び出し元と呼び出し先はどちらも既知であり、例外はもっと安価な分岐に解決できます。

どちらも「安全」ですが、例外を含まないコードは例外を使用するコードよりも少し小さく、少し速くなります。

+0

はい、私は知っています、これらのプログラムは等しくない(私はそれらを見つけた)。私は、この最適化フラグの有無にかかわらずビルドされた実行可能ファイル間の実行時間のこのような大きな違いについて興味があっただけです。もう一度アセンブラ出力を調べて見つけましたが、その部分はインライン展開されていました。一方、私は、直接関数呼び出しがx86で非常に高価であることは知らなかった... – Goofy

関連する問題