1

私のPC(x86)で基本的なシステムをエミュレートする次のコードがあります:

typedef void (*op_fn) ();

void add()
{
   //add Opcode
   //fetch next opcode
   opcodes[opcode]();
}

void nop()
{
   //NOP opcode
   //fetch next opcode
   opcodes[opcode]();
}

const op_fn opcodes[256] =
{
    add,
    nop,
    etc...
};

opcodes[opcode]() インタープリターのパフォーマンスを改善しようとしています。次のように、すべての関数をインライン化するのはどうですか

inline void add()
inline void nop()

それを行うことの利点はありますか?

とにかく速くする方法はありますか?ありがとう

4

3 に答える 3

3

inlineコンパイラがそうする必要がないので、メソッドにフラグを立てるという理由だけで、それは順序というよりもヒントです。

オペコード ハンドラーを配列に格納している場合、コンパイラは関数のアドレスを配列に配置する必要があるため、インライン化できません。

実際、あなたのアプローチには何も問題はありません。パフォーマンスに問題があると本当に思っている場合は、いくつかの指標を取得してください。関数へのポインターのテーブルの概念は新しいものではありません。これは、実際に C++ が仮想関数 (つまり、vtable) を実装する方法です。

于 2016-04-27T13:57:03.450 に答える
2

「インライン」とは、「関数呼び出しを発行しないでください。代わりに、コンパイル時に関数本体を置き換える」ことを意味します。

関数ポインターを介して呼び出すということは、「実行時まで詳細がわからない関数呼び出しを行う」ことを意味します。

この 2 つの機能は根本的に対立しています。(期待できる最善の方法は、十分に高度なコンパイラが、非常に限られた状況で関数ポインターを介して呼び出されている関数を静的に判断し、それらをインライン化できることです。)

switchブロックは通常、関数呼び出しよりもオーバーヘッドが少ないジャンプ テーブルとして実装されるため、関数ポインター配列をswitchブロックに置き換え、インラインを使用すると違いが生じる場合があります。

于 2016-04-27T13:50:50.907 に答える
1

inlineコンパイラへの単なるヒントであり、インライン化が行われることを保証するものではありません。インライン化が多すぎると、実際にはコードが遅くなる可能性があるため(おそらくISO C++ FAQ で) インライン化について読む必要があります(コードの肥大化と関連する仮想メモリの破棄により)。

于 2016-04-27T13:55:33.677 に答える