3

仕事で Linux C++ プログラム設計の問題が発生しました。

関数 f() は 2 つの場所で呼び出されます。インラインとして宣言されています。

1 番目の場所では、f() が 10000 回呼び出されます。呼び出しのオーバーヘッドを減らすために、手動でインライン化 (f() 本体を呼び出し元にコピー) する必要があります。その効果は結果によって確認されています。

2 番目の場所では、1 番目とは異なる目的で f() が 1 回だけ呼び出されます。

さらなる作業のために、f() 内でいくつかの変更を加えることができます。手動でインライン化する場合は、f() 本体の 2 番目の場所に同じ変更を加えて、1 番目と 2 番目の f() が常にまったく同じになるようにする必要があります。

このように1位と2位の同期を取るのは難しい。

デバッグには gdb を使用する必要があるため、マクロは使用しません。

__attribute__ ((always_inline))当社のシステムではサポートされていません。

4

3 に答える 3

2

やや非直感的なコードを生成する可能性がありますが、同じコード片をインライン化されたバージョンとインライン化されていないバージョンの両方で使用できるようにする可能性は次のとおりです (関数をインライン化する必要がある場所が 1 つだけある場合に機能します)。

は、インラインa()または非インラインのいずれかの形式で保持するコードの一部でb()あり、インライン バージョンのa()を埋め込む必要がある関数であるとします。C++ テンプレートを利用し、eg と呼ばれる ean パラメーターでパラメーター化b()します。これで、関数は次のようになります。boolJUST_Ab()

if (!JUST_A) {
    //do something
}
b()
if (!JUST_A) {
    //do something more
}

テンプレート メカニズムは各パラメーター化のコードを個別に生成するため、ブール型パラメーターが最適化されて、次のことを行う 1 つのバリアント ( for JUST_A==false) になります。

//do something
b()
//do something more

そして別のものだけを行います

b()

( の場合JUST_A==true)。どちらかのコードを呼び出すa<true>()か、実行するかによって異なります。a<false>()

これが実際に機能するかどうかは、プログラムの逆アセンブリで確認できますが、そうすべきです。それでも、これは良いコードではないと思います。可能であれば、コードの読みやすさのために他の人が提案した強制インライン化の変形を好むでしょう。

于 2012-11-08T21:52:00.170 に答える
0

機能を 2 回提供します。最初の関数はヘッダーにインラインで実装され、2 番目の関数はインライン関数を呼び出す cpp ファイルに実装されます。

// function_inline.h
inline void function_inline()
{
   // implementation
}

// function.h
void function();

// function.cpp
#include "function.hpp"
#include "function_inline.hpp"
void function() { function_inline(); }

通常のコードは呼び出しますfunction()が、関数をインライン化したい場所でfunction_inline()使用できます。

于 2012-11-09T21:11:04.557 に答える
0

マクロを使用します。デバッグする場合は、マクロから本体をコードにコピーしてデバッグし、完了したらマクロに戻します。状況が少し異常でない限り、コードを正しく理解するために何度もそのコードをステップ実行する必要はありません。

または、 Cogやカスタム スクリプトなどのプリプロセッサの代替手段を使用して、コードが同じままであることを確認することもできます。基本的には、両方のファイルで問題のブロックの周りにマーカーを置き、何かを抽出して比較します。それらが同期しなくなった場合は、ビルドを中断します。

于 2012-11-09T21:21:52.030 に答える