在C语言中如何实现精确计时
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C语言中如何实现精确计时相关的知识,希望对你有一定的参考价值。
参考技术Atime()
头文件:time.h
函数原型:time_t time(time_t * timer)
功能:返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的此时此刻所经过的秒数。
2.clock()
头文件:time.h
函数原型:clock_t clock(void);
功能:该函数返回值是硬件滴答数,要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。比如,在VC++6.0下,这两个量的值都是1000。
3. timeGetTime()
头文件:Mmsystem.h 引用库: Winmm.lib
函数原型:DWORD timeGetTime(VOID);
功能:返回系统时间,以毫秒为单位。系统时间是从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约49.71天。
.NET 中的精确计时
【中文标题】.NET 中的精确计时【英文标题】:Precision timing in .NET 【发布时间】:2009-04-27 22:10:13 【问题描述】:我刚刚看到this question,其中一个答案表明System.Diagnostics.Stopwatch 应该只用于诊断性能,而不是在生产代码中。
在这种情况下,在 .NET 中获得精确计时的最佳方法是什么?我目前正处于使用NAudio 的MIDI 输出功能构建一个非常简单的MIDI 音序器的早期阶段。我希望能够以尽可能少的抖动将 MIDI 消息发送到(比如说)1/10 秒。这是可行的吗,还是上下文切换之类的事情会毁了我的一天?
我目前在控制台应用程序中有一些代码,它连续调用Stopwatch
并在以 150bpm 生成 1/16 音符流时计算抖动。在这种情况下,抖动非常低。不过,我将把它移到另一个线程,所以我不知道是否会保持这种情况。
【问题讨论】:
【参考方案1】:如果您不介意 P/Invoke,可以使用 QueryPerformanceCounter:http://www.eggheadcafe.com/articles/20021111.asp
【讨论】:
+1。性能计数器将为您提供您能找到的最精确、最轻的计数器。它不像其他实现那样简单。 据我了解,Stopwatch 使用 QueryPerformanceCounter(如果有)。我没有反对 QPC 并且之前在 C++/Win32 应用程序中使用过它,但是我不知道 CLR 的较低级别发生了什么,所以想知道是否有更好的方法。 你说得对,秒表确实使用 QueryPerformanceCounter - 我没有意识到。阅读了另一个问题后,我认为有人建议不要在生产中使用 Stopwatch 的唯一原因是它会带来一些开销,但我想这非常小,而且很容易测量。【参考方案2】:您还可以使用本机流式传输 MIDI API。我不认为它在 NAudio 中,但您可以查看 C# Midi Toolkit 以查看它是否支持它。否则,您有两个示例说明如何执行本机 MIDI API P/Invoke,并且可以自己动手...
【讨论】:
NAudio 中有一些流媒体 MIDI API 的包装器,但它们还没有完成。不过,可能会为您指明正确的方向【参考方案3】:Windows multimedia timer 声明它允许“应用程序以硬件平台可能的最大分辨率(或精度)来安排计时器事件。”
它用作示例的应用程序是 MIDI 音序器。
【讨论】:
【参考方案4】:我是DryWetMIDI 的作者。该库具有播放功能,可在 WinMM 高精度计时器的帮助下工作。 Timer 被封装到 MidiClock 类中,因此您可以使用它来驱动您的 MIDI 操作:
var midiClock = new MidiClock(true, new HighPrecisionTickGenerator(), TimeSpan.FromMilliseconds(1));
midiClock.Ticked += OnTick;
OnTick
将使用此代码每 1 毫秒调用一次。
【讨论】:
以上是关于在C语言中如何实现精确计时的主要内容,如果未能解决你的问题,请参考以下文章