46

精神的には、C ++コンパイルがアセンブラーに変換するときに、try / throw/catchが舞台裏でどのように見えるのか常に疑問に思っていました。しかし、私はそれを使用したことがないので、それをチェックすることは決してありませんでした(一部の人々は怠惰と言うでしょう)。

sを追跡するために通常のスタックが使用されますtryか、それともこの目的のためだけに個別のスレッドごとのスタックが保持されますか?MSVCとg++の間の実装は大きいですか、小さいですか?疑似asmを見せてください(IA-32も大丈夫です)ので、自分でチェックする必要はありません!:)

編集:これで、IA-32処理に関するMSVCの実装の基本を理解できました。IA-32のg++、またはその他のCPUについて知っている人はいますか?

編集2(11年後):パフォーマンスに関する いくつかのデータがあります。また、ソースコードを無料で利用できるようにしました。

4

3 に答える 3

26

例外ハンドラーの実装が不十分な場合、try 句が入力されると実行時スタックの各 try 句に対してある種の例外ハンドラー ブロックがプッシュされ、try 句が終了するとそれがポップされます。最後にプッシュされた例外ハンドラ ブロックのアドレスを保持する場所も維持されます。通常、これらの例外ハンドラはチェーン化されているため、最新バージョンから古いバージョンへのリンクをたどることで見つけることができます。例外が発生すると、最後にプッシュされた EH ハンドラー ブロックへのポインターが見つかり、その "try" 句の EH ケースの処理がチェックされます。EH ケースでヒットすると、プッシュされた EH のポイントまでスタックのクリーンアップが発生し、制御が EH ケースに移ります。EH にヒットがない場合、次の EH が検出され、プロセスが繰り返されます。Windows 32 ビット SEH スキームは、これのバージョンです。

例外が発生しない場合でも、プログラムは各 try 句 (プッシュしてからポップ) ごとにランタイム コストを支払うため、これは適切な実装ではありません。

適切な実装では、try 句が発生する範囲のテーブルを単純に記録します。これは、try 句に出入りするためのオーバーヘッドがゼロであることを意味します。(私のPARLANSE並列プログラミング言語はこの手法を使用しています)。例外は、テーブル内の例外ポイントの PC を検索し、テーブルによって選択された EH に制御を渡します。EH コードは、必要に応じてスタックをリセットします。速くてきれい。Windows 64 ビット EH はこのタイプだと思いますが、よく見ていません。

[2020 年 4 月編集: 最近 PARLANSE 例外のコストを測定しました。例外がない場合は 0nS (設計による)。3Ghz i7 では、「スロー」から「キャッチ」、「確認」まで 25ns (エンプティ キャッチの終了)。OPは、最も単純な種類のC++例外処理を約1000nsで測定するリンクと、例外または例外なしで57nsでクロックインする文字通り非標準の処理スキームを追加しました。C++ バージョンの CPU クロック レートは少し遅いため、これらの数値は大まかな比較にすぎません。]

于 2009-08-25T22:05:01.050 に答える
5

C++ 標準委員会は、「C++ のパフォーマンス」に関するテクニカル レポートを発行し、C++ の機能がどのように速度を低下させるかについての多くの神話を暴きました。これには、例外処理の実装方法に関する詳細も含まれています。この技術レポートのドラフトは無料で入手できます。セクション 5.4.1 を確認してください。「例外処理の実装の問題とテクニック」.

于 2009-10-03T06:37:44.277 に答える