2012-03-23 7 views
0

タイトなループを使ってストップウォッチの出力を監視するコードを書きました。このループは、最後の反復から経過したティックの数を追跡します。私は500マイクロ秒のジャンプを毎秒20回観測していますが、他のほとんどの反復は<1μsです。ストップウォッチはタイトループの繰り返しの間に500μsジャンプするようです

なぜ私はこれらのジャンプを見ているのか説明できますか?

私が試した:

  1. デバッガ
  2. の外のリリースでビルド実行中のスレッドの優先度(最高/ AboveNormalは物事を悪化させる)
  3. を変更するプロセッサアフィニティ(効果なし)
  4. を設定します最適化

私のコードは以下のとおりです。

 Stopwatch sw = new Stopwatch(); 
     int crossThresholdCount = 0; 
     long lastElapsedTicks = 0; 
     long lastPrintTicks = 0; 
     Console.WriteLine("IsHighResolution: " + Stopwatch.IsHighResolution); 
     Console.WriteLine("Frequency: " + Stopwatch.Frequency); 

     sw.Start(); 

     long thresholdTicks = 5000; // 10000 ticks per ms 
     while (true) 
     { 
      long tempElapsed = sw.ElapsedTicks; 
      long sincePrev = tempElapsed - lastElapsedTicks; 
      lastElapsedTicks = tempElapsed; 

      if (sincePrev > thresholdTicks) 
       crossThresholdCount++; 

      // print output 
      if (crossThresholdCount > 0 && tempElapsed - lastPrintTicks > TimeSpan.TicksPerSecond) 
      { 
       lastPrintTicks = tempElapsed; 
       Console.WriteLine("crossed " + crossThresholdCount + " times"); 
       crossThresholdCount = 0; 
      } 
     } 
+0

JIT効果を排除するためにプログラムで2回テストコードを実行しようとしましたか? –

+0

console.writelineコードをstore to list変数に置き換えて、ループが完了した後ですぐにすべてのタイミングを出力するとどうなりますか? – rism

答えて

5

ほとんどの場合、プリエンプティブなタスク切り替えが行われています。これは、オペレーティングシステムがプログラムを中断し、他のプログラムを実行するために消えたときです。これは、Windows 95(Win 3.1以前では協調的なマルチタスキングがあったため、CPUを望みどおりに保持することができたため)でした。

ところで、実行を正確に実行するためのより良い方法があります。QueryThreadCycleTimeはコードが実行されているときだけCPUサイクルをカウントし、そのような一時停止を除外します。

+0

Win 3.1は、実際にはDOSアプリケーション用のプリエンプティブマルチタスクとWindowsアプリケーション用の共同マルチタスクを行っていました。 –

+0

+1 for QueryThreadCycleTime – rism

+0

スレッドの優先度を最高に設定しないと、プリエンプトを減らす/防止できませんか?最高に設定すると、ジャンプの数は毎秒20から毎秒200になります –

3

あなたのテストは実際には意味がありません...あなたのプロセスはあなたのマシンで実行する唯一のものではありません。システムは各スレッドに順番にプロセッサ時間を与えます。そのため、ループがまったく実行されていない時間があり、「ジャンプ」が説明されています。

関連する問題