我正在编写一个探查器,只要函数进入或退出就会查询计时器。因此,它可能每秒查询数千次。
最初我使用 QueryPerformanceCounter ,尽管事实上它的分辨率很高,但事实证明非常慢。根据{{3}}问题,当我在分析器中使用QPC时,我也有明显的减速,但可能不是那么糟糕的1-2ms数字。如果我用 GetTickCount 替换它,我没有注意到任何减速,但该功能对于分析来说是不准确的。
上述问题提到亲和面具。我尝试使用SetProcessAffinityMask(GetCurrentProcess(), 1)
绑定它,但它根本没有提高性能。
我不知道它是否重要,但到目前为止,我在Linux主机上运行VirtualBox的Windows上进行了测试。这可能是问题吗?
答案 0 :(得分:0)
我在Windows上了解的最高分辨率计时器是winmm.dll
这是我为满足自己的性能测试而烦恼的课程 - 给我一个旋转:
public class HighResTimer
{
private delegate void TimerEventHandler(int id, int msg, IntPtr user, int dw1, int dw2);
private const int TIME_PERIODIC = 1;
private const int EVENT_TYPE = TIME_PERIODIC;
[System.Runtime.InteropServices.DllImport("winmm.dll")]
private static extern int timeSetEvent( int delay, int resolution, TimerEventHandler handler, IntPtr user, int eventType);
[System.Runtime.InteropServices.DllImport("winmm.dll")]
private static extern int timeKillEvent(int id);
[System.Runtime.InteropServices.DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int msec);
[System.Runtime.InteropServices.DllImport("winmm.dll")]
private static extern int timeEndPeriod(int msec);
private int _timerId;
private TimerEventHandler _handler = delegate {};
public event EventHandler OnTick;
public HighResTimer(int delayInMs)
{
timeBeginPeriod(1);
_handler = new TimerEventHandler(timerElapsed);
_timerId = timeSetEvent(delayInMs, 0, _handler, IntPtr.Zero, EVENT_TYPE);
}
public void Stop()
{
int res = timeKillEvent(_timerId);
timeEndPeriod(1);
_timerId = 0;
}
private void timerElapsed(int id, int msg, IntPtr user, int dw1, int dw2)
{
OnTick(this, new EventArgs());
}
}
答案 1 :(得分:0)
直接使用RDTSC指令结束。所以我在GCC中为它编写了一个包装器:
static inline unsigned long long rdtsc(void)
{
unsigned hi, lo;
asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
没有减速,显然比QueryPerformanceCounter具有更高的分辨率。
代码基于this answer。