2

私は次のコードを持っています:

while(flag)
{
  Thread.SpinWait(1);
}

SpinWait以下はinの実装ですRotor(sscli20\clr\src\vm\comsynchronizable.cpp)

FCIMPL1(void, ThreadNative::SpinWait, int iterations)
{
    WRAPPER_CONTRACT;
    STATIC_CONTRACT_SO_TOLERANT;

    for(int i = 0; i < iterations; i++)
        YieldProcessor();
}
FCIMPLEND

Thread.SpinWait呼び出されたときにインライン化されますか?

そうでない場合、各ループ サイクルでより多くの時間を費やしstack operations(push and pop)、CPU の実行リソースをより多く消費します。

はいの場合、スタック操作(プッシュとポップ)を含む標準関数命令シーケンスとして実装されている間、どのようにclrそれを達成しますか?ThreadNative::SpinWait

Eren のテストでは、デバッグ モードでインラインは発生しません。clr 最適化してインライン コードを生成することは可能ですか?

まとめ: ご回答ありがとうございます。いつの日か clr が MethodImplOptions.InternalCall などの 1 つのメカニズムによってプリコンパイル済みコードをインライン化できるようになることを願っています。次に、スタック操作を排除し、フラグのチェックとスピン待機にほとんどの時間を費やすことができます (nop よりも少ない CPU リソースを消費します)。

4

2 に答える 2

4

見てみるのが一番。サンプルコード:

static void Main(string[] args)
{
    while (true) 
        Thread.SpinWait(1);
} 

最適化された逆アセンブリは次を示します。

x86:

00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  mov         ecx,1 
00000008  call        6F11D3FE 
0000000d  jmp         00000003 

x64:

00000000  sub         rsp,28h 
00000004  mov         ecx,1 
00000009  call        000000005F815434 
0000000e  jmp         0000000000000004 
00000010  add         rsp,28h 
00000014  ret 

したがって、どちらの場合 もインライン展開はありません。

たぶん私は何かを見逃しているかもしれませんが、CPUを回転させるととにかくサイクルが消費されるため、スタック操作を気にする理由がよくわかりません(全体の目的は譲らないことです)。

于 2013-10-31T09:02:55.940 に答える