3

ここSOでもインターネットでも同様の質問/回答を見つけることができません。この質問と同じくらい役に立たないのは、MSILを読んでいるときに頭に浮かんだ質問かもしれません。これが実際的な質問でなくても、私のシナリオで IL 操作の実行がどのように機能するかを理解したいと思っています。

前提:

MSIL コマンドと関数の実行は、次の 3 つの手順で行われることに注意してください。

  1. コマンド オペランドまたは関数パラメーターをスタックにプッシュします。
  2. MSIL コマンドを実行するか、関数を呼び出します。コマンドまたは関数は、スタックからオペランド (パラメーター) をポップし、スタックの結果 (戻り値) にプッシュします。
  3. スタックから結果を読み取ります。

ステップ 1 と 3 はオプションです。たとえば、void 関数は戻り値をスタックにプッシュしません。

どのくらいの「処理能力」が必要かを決定するのはメソッドの機能であることは理解していますが、好奇心のために、次の 2 つの非常に基本的なメソッドを考えてみましょう。

最初の方法:

void Method1()
{
  var result = 1+1;
}

2 番目の方法:

int Method2()
{
  var result = 1+1;
  return result;
}

質問:

void メソッドは戻り値をプッシュしない (または暗黙的な戻り値がある) ため、これは、2 番目のメソッドとは対照的に、実行時に必要なオーバーヘッドが少ないことを意味しますか?

4

2 に答える 2

6

ただし、MSIL は実行も解釈もされないことに注意してください。MSIL は、仮想マシンで実行されるコンパイル済みコードの表現です。ただし、JIT コンパイラは MSIL をマシン コード (x86 など) に変換します。x86 は、スタックベースの仮想マシンとは根本的に異なります。

最も基本的なレベルでは、関数はレジスタに値を返します。レジスタが十分に大きいと仮定します。64 ビット値 (参照、long 整数、double、およびより小さい値の型) に固執しましょう。これらは RAX レジスターで返すことができます。あなたの些細な例では、2 つの関数に対して生成されたマシン コードに違いはありません。つまり、次のMethod1ようになります。

mov rax, 1
inc rax
ret

(そして、はい、私はスマート コンパイラが に折りたたまれることを知ってい1+1ます2。そこにメモリ アクセスがあったと仮定しましょう。いいですか?)

Method2返される値はすでに RAX レジスタにあるため、同じになります。

したがって、64 ビット以下の量を操作している場合、値を返すメソッドと値を返さないメソッドの違いは、ほとんどの場合、たとえあったとしても、それをロードするために必要な命令だけが異なります。適切なレジスタに値を返します。これは通常、単一のmov命令です。それは、物事が行われる順序と、コンパイラーと JITer が物事をどれだけうまく最適化するかに依存します。

于 2012-08-30T16:03:06.533 に答える
3

すべてが均等であるため、何かを実行すると、何も実行しない場合よりも遅くなります。

ただし、最初のメソッドの実装は次のようになることに注意してください。

void Method1()
{
}

NullReferenceException()インライン化後、それは呼び出されません (これが別のオブジェクトのインスタンス メソッドである場合、呼び出しがフィールドの読み取りに置き換えられる可能性はほぼあります。null. 静的である場合、同じオブジェクトから呼び出された場合、またはオブジェクトを null にすることはできないとコンパイラが判断した場合は、それもありません。コードはありません。

一方、2 番目の方法は次のようになります。

int Method2()
{
  return 2;
}

インライン化後、値を使用する呼び出しは次のようになります。

x = Method2();

に:

x = 2;

値が使用されていない場合は、それさえありません。最初とまったく同じになります。

この種のことが起こっているということは、呼び出しがインライン化されていない場合でも、何かが返されるかどうかなどの小さな違いは、より大きな要因に対するノイズでさえないため、ほとんどが失われ、直感に反して発生する可能性があることを意味します (最適化パスが不明瞭な方法で取られるかどうかに影響します)。例: 値が生成され、それをレジスターに入れることによって「返されます」が、計算時にとにかくそこにあった可能性があります。したがって、それを「返す」ためのコストはゼロです。

于 2012-08-30T16:02:37.080 に答える