秒表似乎在紧密循环的迭代之间跳跃500μs

时间:2012-03-23 21:47:15

标签: c#

我写了一些代码,用紧密循环监视秒表的输出。该循环跟踪自上次迭代以来经过的滴答数。我观察到每秒20次跳跃500微秒,而大多数其他迭代次数<1μs。

有人可以解释为什么我会看到这些跳跃吗?

我试过了:

  1. 设置处理器关联(无效)
  2. 更改线程优先级(Highest / AboveNormal使事情变得更糟)
  3. 在调试器外运行
  4. 使用优化发布版本
  5. 我的代码如下:

            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;
                }
            }
    

2 个答案:

答案 0 :(得分:5)

您很可能会看到抢占式任务切换。这是操作系统暂停程序,然后执行其他程序。这是Windows 95以来的情况(Win 3.1和更早版本具有协作式多任务处理,您可以根据需要保留CPU)。

顺便说一下,有一种更好的方法可以准确地计算执行时间:QueryThreadCycleTime,它只在代码执行时计算CPU周期,因此排除了这些暂停。

答案 1 :(得分:3)

您的测试没有意义......您的过程不是唯一可以在您的计算机上运行的过程。系统依次为每个线程提供处理器时间,因此有一段时间你的循环根本没有运行,这就解释了“跳跃”。