【问题标题】:PerformanceCounter in while loop循环中的 PerformanceCounter
【发布时间】:2012-06-08 00:26:27
【问题描述】:

我目前正在尝试编写一个每秒准确运行 100 次相同代码的应用程序。我已经使用 .NET 框架的内置计时器进行了一些测试。我测试了 System.Threading.Timer 类、System.Windows.Forms.Timer 类和 System.Timers.Timer 类。对于我正在尝试做的事情,它们似乎都不够准确。 我发现了 PerformanceCounters 并且目前正在尝试在我的应用程序中实现它。 但是,我的程序在空闲时占用了 CPU 的整个内核时遇到了一些麻烦。 我只需要它每秒激活 100 次。我的循环如下所示:

long nextTick, nextMeasure;

QueryPerformanceCounter(out start);
nextTick = start + countsPerTick;
nextMeasure = start + performanceFrequency;

long currentCount;
while (true)
{
    QueryPerformanceCounter(out currentCount);

    if (currentCount >= nextMeasure)
    {
        Debug.Print("Ticks this second: " + tickCount);
        tickCount = 0;
        nextMeasure += performanceFrequency;
    }

    if (currentCount >= nextTick)
    {
        Calculations();
        tickCount++;

        nextTick += countsPerTick;
    }
}

如您所见,大多数情况下,程序将通过不断地运行 while 循环来等待再次运行 Calculations()。有没有办法阻止这种情况发生?我不想降低运行我的程序的计算机的速度。 不幸的是,System.Thread.Thread.Sleep 也很“不准确”,但如果没有其他解决方案,我可以使用它。

我基本上要问的是:有没有办法让无限循环减少 CPU 密集度?有没有其他方法可以准确地等待特定的时间?

【问题讨论】:

    标签: c# multithreading winapi cpu performancecounter


    【解决方案1】:

    我相信您知道,Windows 不是实时操作系统,因此永远无法保证您的代码会随心所欲地运行。

    话虽如此,让给其他线程最有效的方法可能是使用 Thread.Sleep() 作为计时器。如果您想要比默认值更高的精度,您可以发出一个 timeBeginPeriod ,其所需的分辨率低至一毫秒。该函数必须是从 winmm.dll DLLImported。

    【讨论】:

    • 非常感谢您的快速回复。我知道 Windows 不是实时操作系统这一事实。不过,我不知道您可以使用您发布的功能要求降低分辨率。谢谢!我将对此进行更多研究,看看它是否有助于我的程序对 CPU 更友好。
    【解决方案2】:

    timeBeginPeriod(1) 与普通计时器或Thread.Sleep 一起工作应该不错。

    请注意,这具有全局影响。有人声称它会增加功耗,因为它会强制 Windows 计时器更频繁地运行,从而缩短 CPU 睡眠时间。这意味着您通常应该避免它。但是,如果您需要高度准确的计时,它肯定是比忙碌等待更好的选择。

    【讨论】:

    • 感谢您的回复!我现在使用了 PerformanceCounter 和 Thread.Sleep 的组合,它似乎对我正在做的事情足够准确。我不断得到每秒 100 个滴答声,我的 CPU 使用率下降到 0-1%。所以不需要增加分辨率和可能的功耗,是吗? :)
    • @haiyyu 据我所知,启用timeBeginPeriod(1) 会在一定程度上增加功耗。但肯定不如忙碌等待。不幸的是,我对此没有确切的数字。
    • 好吧,那么我想知道我没有使用这两种方法是件好事。 :)
    • 如果您对几个蜱虫聚集在一起感到满意,那很好。但是,如果您希望滴答声相隔 10 毫秒,则需要 timeBeginPeriod。如果没有它也能满足您的要求,那当然很好。
    • 将多个刻度捆绑在一起不是问题。它们应该只在 1 秒内稍微分布。它确实很好,因为它工作得很好。
    猜你喜欢
    • 2018-03-11
    • 2012-05-11
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多