我正在写一个分析器,在函数进入或退出时查询定时器。 所以有可能每秒钟查询数千次 。
最初,我使用了QueryPerformanceCounter ,尽pipe事实上它的分辨率很高,但结果却相当缓慢 。 根据QueryPerformanceCounter被调用时会发生什么? 问题我在分析器中使用QPC时也有明显的减速,但可能不是那么糟糕的1-2ms数字。 如果我用GetTickCountreplace它,我不会注意到任何放缓,但该function是不准确的分析。
提到的问题提到亲和力口罩。 我试图使用SetProcessAffinityMask(GetCurrentProcess(), 1)
绑定它,但它并没有提高性能。
我不知道是否重要,但到目前为止,我已经在Linux主机上的VirtualBox上运行的Windows上进行了testing。 这可能是问题吗?
我知道在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()); } }
直接使用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更高的分辨率。
代码基于这个答案 。