首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.Net中的计时器和回圈准确吗?

.Net中的计时器和回圈准确吗?
EN

Stack Overflow用户
提问于 2012-07-17 21:26:58
回答 4查看 3.8K关注 0票数 2

在开发一个计算555定时器芯片产生的脉冲频率和脉宽的程序时,通过PC并行口进入PC机。我注意到每次运行代码时都会显示不同的值,因此我开始测试循环和计时器的准确性。我已经运行了以下代码,并指出它们是不准确的(我可能是错的,请纠正我,如果是!):

定时器的

代码语言:javascript
复制
    int sec = 0;
    private void button2_Click(object sender, EventArgs e)
    {
        sec = DateTime.Now.Second;
        i = 0;
        timer1.Enabled = true;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (sec == DateTime.Now.Second)
        {
            i++;
        }
        else
        {
            timer1.Enabled = false;
            MessageBox.Show(i.ToString(),"Timer Output");
        }
    }

输出:应该是相同的,但是:

For循环:

代码语言:javascript
复制
    private void button1_Click(object sender, EventArgs e)
    {
        i = 0;
        CheckForIllegalCrossThreadCalls = false;
        Thread t1 = new Thread(LoopTest);
        t1.Start();
    }

    void LoopTest()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        this.Cursor = Cursors.WaitCursor;
        while (true)
        {
            if (sw.ElapsedMilliseconds != 1000)
            {
                i++;
            }
            else
            {
                break;
            }
        }
        sw.Stop();
        this.Cursor = Cursors.Default;
        MessageBox.Show(i.ToString(), "Loop Output");
    }

输出:应该是相同的,但是:

我该怎么做才能使循环和计时器准确,有什么办法可以做到吗?或者我要去硬和复杂的C代码和DOS?

我认为这是我在这个问题中错误价值观的根本原因:计数并口输入频率- C#

EN

回答 4

Stack Overflow用户

发布于 2012-07-17 21:32:57

1)不要将DateTime.Now用于性能度量,而是使用StopWatch

2) "OUTPUT: Should be same, but ..

他们为什么要这样?您正在非实时操作系统(实时操作系统)上运行托管/JIT‘’ed代码。你的代码可以在任何时候被弹出,如果操作系统想要的话。是什么让您相信,在这个环境中运行相同的代码N次,总是会产生如此小的结果?

3) Windows上的定时器具有~15 on的分辨率。对于非常精确的计时,最好的选择是支持它的系统上的HighPerformanceTimer API。你还没给我们看过计时器的间隔。

你在这里没有考虑很多变量,你的预测是基于错误的假设。你到底测量了多少次这个代码?您是否考虑到了第一次编译它所需的时间?你在发布模式下运行吗?通过VS?背景中有许多任务在运行吗?我可以继续。

票数 16
EN

Stack Overflow用户

发布于 2012-07-18 08:44:18

仔细的实现允许在大多数windows平台上测量时间周期,其精度仅为几微秒。注意以下事实:

  1. Windows不是实时操作系统:这在这里不重要!
  2. 使用进程/线程优先级:SetPriorityClass位于REALTIME_PRIORITY_CLASSSetThreadPriority位于THREAD_PRIORITY_TIME_CRITICAL。确保有安全的代码,因为这些优先级可以在调用线程繁忙时锁定系统。(Process.PriorityClass和Thread.Priority并不完全能够将优先级提高到所需的水平。)
  3. 可能通过多媒体定时器增加系统的中断周期和时间更新间隔。(有各种各样的.NET项目封装了这些多媒体计时器功能。)
  4. 在多核系统中,核的选择也会影响精度。强制线程在Processor0上等待计时器事件是有利的。SetThreadAffinityMask函数允许将线程绑定到特定的cpu。(有关.Net应用程序,请参阅Thread.ProcessorAffinity。)
  5. QueryPerformanceCounterQueryPerformanceFrequency作为高频时间测量的参考值。( .Net应用程序见:创建QueryPerfCounter包装器类)
  6. 确保校准了性能计数器频率的值。QueryPerformanceFrequency返回的值通过一个偏移量和一些热漂移偏离观测值。这可能/会导致许多美国/s的错误。请参阅Windows时间戳项目,以了解如何进行这样的校准。

是的,你可能需要进行一些硬编码。但是在windows平台上可以观察到微秒计时非常可靠。

注意: Windows不是一个实时操作系统.但窗户上可用的计时器非常精确。他们做的正是他们应该做的,并且做得非常精确。事实上,有很多关于windows计时器及其准确性的抱怨,因为它们的行为在很大程度上取决于底层硬件。这也是为什么文档有许多缺陷的原因。强烈建议对硬件进行诊断,以便找到单独的时间服务功能。不幸的是,这导致任何程序都有一些额外的代码行是独立于平台的。

票数 13
EN

Stack Overflow用户

发布于 2012-07-17 21:34:20

首先,您不知道调用button2_click的当前秒有多远。所以,这基本上是随机的,当MessageBox被显示时,还剩下多少秒--这就是你所看到的。

其次,一个循环在一段时间内获得多少CPU周期与准确性无关。

一个给定线程得到多少个周期取决于系统中还发生了什么。如果系统决定整个周期需要转到另一个进程,那么您的线程就会“饥饿”一段时间。

也许你可以详细说明你真正想做的事情,有人可以给你一些建议。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11531128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档