20011010wo 发表于 2016-8-22 21:59:34

高精度计时器HighAccuracyTimer

本帖最后由 20011010wo 于 2016-8-22 22:25 编辑



点击停止后将会计算从上一次点击开始所用的时间,如果没有点击开始……则时间近似为窗口显示的时间 + 校准所用时间(500ms)

32位静态编译

原理:利用某些设备主板上的晶振,开始后将会连续5次校准多核CPU采用QueryPerformanceCounter的问题 QueryPerformanceCounter的运行情况是依赖于CPU的,当CPU是多核时,在某一线程内调用QueryPerformanceCounter,线程会切换于不同的核心之间,这时候QueryPerformanceCounter返回值是不确定的。
多核CPU使用QueryPerformanceCounter 当需要在某一进程中获取时间,需要将该线程绑定在某一固定的核心上,这样获取的高精度计时器才是可靠的。通过SetThreadAffinityMask可以实现这一目的

如:SetThreadAffinityMask(GetCurrentThread(),0x00000001);//绑定当前线程到CPU 1号核心

附赠高精度时间类(C++)
class HighAccuracyTimer:private Noncopyable
{
public:
        HighAccuracyTimer()
        {
                succeed = QueryPerformanceFrequency(&freq);
                oldMask = SetThreadAffinityMask(GetCurrentThread(), 0x00000001);
                QueryPerformanceCounter(&begin);       
        }

        ~HighAccuracyTimer()
        {
                SetThreadAffinityMask(GetCurrentThread(), oldMask);
        }

        void Start()
        {
                QueryPerformanceCounter(&begin);
        }
        void End()
        {
                QueryPerformanceCounter(&end);
        }
        __int64 Correct()
        {
                QueryPerformanceCounter(&correct_begin);
                QueryPerformanceCounter(&correct_end);
                correct = correct_end.QuadPart - correct_begin.QuadPart;
                return correct;
        }
        unsigned __int64 Count()
        {
                return (__int64)(end.QuadPart - begin.QuadPart);
        }

        unsigned __int64 Frequency()
        {
                return freq.QuadPart;
        }
        long double Seconds()
        {
                return (end.QuadPart - begin.QuadPart - correct) / ((long double)freq.QuadPart);
        }
        long double MillSeconds()
        {
                return (end.QuadPart - begin.QuadPart - correct) / ((long double)freq.QuadPart) * 1000.0L;
        }
        long double MicroSeconds()
        {
                return (end.QuadPart - begin.QuadPart - correct) / ((long double)freq.QuadPart) * 1000000.0L;
        }
        BOOL succeed;

private:

        LARGE_INTEGER freq;
        LARGE_INTEGER begin, end, correct_begin, correct_end;
        ULONG_PTR oldMask;
        __int64 correct = 0LL;
};


nkc3g4 发表于 2016-8-24 14:55:59

校准后的0 1 是什么意思

20011010wo 发表于 2016-8-24 14:59:02

nkc3g4 发表于 2016-8-24 14:55
校准后的0 1 是什么意思

执行开始计时然后立刻执行停止计时所用时间/晶振精度.理论上为0

nkc3g4 发表于 2016-8-24 14:59:55

20011010wo 发表于 2016-8-24 14:59
执行开始计时然后立刻执行停止计时所用时间/晶振精度.理论上为0

那为什么会有1

20011010wo 发表于 2016-8-24 15:00:33

nkc3g4 发表于 2016-8-24 14:59
那为什么会有1

所以要校准

20011010wo 发表于 2016-8-24 15:01:28

nkc3g4 发表于 2016-8-24 14:59
那为什么会有1

以后的计数都要减去1
页: [1]
查看完整版本: 高精度计时器HighAccuracyTimer