概述
代码优化时需要用到精确的计时器。常用的有GetTickCount函数,可以达到毫秒级的精度。但还是很不够的,这时可以采用提高循环次数的办法。另外,还有一个精度更高的定时——“高分辨率性能计数器”(high-resolution performance counter),它提供了两个API函数,取得计数器频率的QueryPerformanceFrequency和取得计数器数值的QueryPerformanceCounter。实现原理是利用计算机中的8253,8254可编程时间间隔定时器芯片实现的。在计算机内部有三个独立的16位计数器。
计数器可以以二进制或二—十进制(BDC)计数。计数器每秒产生n次脉冲,每次脉冲使计数器的数字减一,产生频率是可变的,用QueryPerformanceFrequency可以得到,比如我的电脑(P4 2.8G)返回的是2793050000,P4 3G则返回2992530000。QueryPerformance Counter可以得到当前的计数器值。所以只要你的计算机够快,理论上精度可以达到1/2793050000秒或者更高。
先看高分辨率计数器的类
public class Counter
{
protected Int64 m_freq;
protected bool m_usePerf = true; //高分辨率计数器是否可用
public Counter()
{
if (QueryPerformanceFrequency(ref m_freq) == 0)
{
m_freq = 1000;
m_usePerf = false;
}
}
// 获取当前的Tick
public Int64 CurrentTick()
{
if (m_usePerf)
{
Int64 curTick = 0;
QueryPerformanceCounter(ref curTick);
return curTick;
}
return (Int64)Environment.TickCount;
}
// 获取两个时间内的滴答数
private Int64 GetSafeDelta(Int64 curTime, Int64 prevTime, Int64 maxValue)
{
if (curTime < prevTime)
return curTime + maxValue - prevTime;
return curTime - prevTime;
}
// 获取两个Tick间的时间(毫秒)
public Int64 DeltaTime_ms(Int64 curTick, Int64 prevTick)
{
if (m_usePerf)
return 1000 * GetSafeDelta(curTick, prevTick, Int64.MaxValue) / m_freq;
return GetSafeDelta(curTick, prevTick, Int32.MaxValue);
}
[System.Runtime.InteropServices.DllImport("KERNEL32.dll")]
internal static extern int QueryPerformanceFrequency(ref Int64 lpFrequency);
[System.Runtime.InteropServices.DllImport("KERNEL32.dll")]
internal static extern int QueryPerformanceCounter(ref Int64 lpPerformanceCount);
}
应用:
Counter counter = new Counter();
flag = true;
while(flag)
{
Int64 startTick = counter.CurrentTick();
TickCount++;
if(TickCount % FramesPerSecond == 0)
label9.Text = (TickCount / FramesPerSecond).ToString();
// 按帧更新屏幕
label3.Text = TickCount.ToString();
Int64 deltaMs = counter.DeltaTime_ms(counter.CurrentTick(), startTick);
Int64 targetMs = (Int64)(1000.0F * SecondsPerFrame); // 如果FramesPerSecond不能被1整除,那么这里会有走时误差
dt = dt.AddMilliseconds(targetMs);
label1.Text = dt.ToString() + " " + dt.Millisecond;
if (deltaMs <= targetMs)
{
label4.Text = counter.CurrentTick().ToString();
// 在时间帧到达之前空循环
while (counter.DeltaTime_ms(counter.CurrentTick(), startTick) < targetMs)
{
Thread.Sleep(0);
Application.DoEvents();
}
}
}
完整代码下载
转载于:https://www.cnblogs.com/Truly/archive/2006/04/17/377606.html
最后
以上就是清秀豌豆为你收集整理的高分辨率计数器和定时器应用的全部内容,希望文章能够帮你解决高分辨率计数器和定时器应用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复