C get system time to microsecond accuracy on windows? [duplicate]
Asked Answered
P

3

9

Possible Duplicate:
measuring time with resolution of microseconds in c++?

Hi,

Is there a simple way i can get the system time on a Windows machine, down to microsecond accuracy?

Perdition answered 31/12, 2010 at 5:13 Comment(1)
Duplicate of https://mcmap.net/q/1173814/-c-windows-timeDrin
S
12

Look at GetSystemTimeAsFileTime

It gives you accuracy in 0.1 microseconds or 100 nanoseconds.

Note that it's Epoch different from POSIX Epoch.

So to get POSIX time in microseconds you need:

    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    unsigned long long tt = ft.dwHighDateTime;
    tt <<=32;
    tt |= ft.dwLowDateTime;
    tt /=10;
    tt -= 11644473600000000ULL;

So in such case time(0) == tt / 1000000

Shirashirah answered 31/12, 2010 at 7:46 Comment(9)
More likely it's the time expressed in 100-nanoseconds rather than 100-nanosecond accuracy?Abominable
You could also use GetSystemTime()... but the issue is, it's absolute time, not relative time. It isn't good for use inside a program to figure out time elapsed, as absolute time can change for various random reasons (e.g. time sync).Lombard
@Lambert GetSystemTime as milliseconds accuracy, it is not good enough, also it used date format so it is hard to calculate differencesShirashirah
@Abominable yes, you are right. But it is the most accurate measurement that Win32API can giveShirashirah
From KeQuerySystemTime: "System time is typically updated approximately every ten milliseconds."Hysteric
" GetSystemTime as milliseconds accuracy, it is not good enough" -- So converting it to a file time will magically make it more accurate? "the most accurate measurement that Win32API can give" -- directly, but not the most accurate that can be calculated. The interval is 10 ms, but the precision of that 10 ms is very high, as can be determined by using QueryPerformanceCounter. Spin on that until GetSystemTime changes, and you can do very accurate timing.Seton
I'm not sure how to interpret the output of "tt/1000000". For example, I'm getting 1350054353. Could someone help me out?Fluorspar
You are confusing accuracy with precision.Firstrate
See also: GetSystemTimePreciseAsFileTime()Possessed
W
4

Like this

unsigned __int64 freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
double timerFrequency = (1.0/freq);

unsigned __int64 startTime;
QueryPerformanceCounter((LARGE_INTEGER *)&startTime);

//do something...

unsigned __int64 endTime;
QueryPerformanceCounter((LARGE_INTEGER *)&endTime);
double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);
Wiltz answered 31/12, 2010 at 6:57 Comment(1)
QueryPerformanceCounter does not returns system time but high resolution counter.Unbated
L
-1

What we really need is a high-resolution GetTickCount(). As far as I know, this doesn't really exist.

If you're willing to use a hackish way to solve this (that would probably only work on some versions of Windows like XP), look here at ReactOS. Then try this code:

long long GetTickCount64()
{
    return (long long)
        ((((unsigned long long)*(unsigned long int*)0x7FFE0000
           * (unsigned long long)*(unsigned long int*)0x7FFE0004)
         * (unsigned long long)10000) >> 0x18);
}

Tweaking it might give you what you need in some versions of Windows.

Lombard answered 31/12, 2010 at 9:47 Comment(8)
GetTickCount is always in milliseconds. The 32-bit GetTickCount implementation you posted is no different from the old Win32 implementation.Hysteric
Exactly -- that's why I said tweak it. You can do smaller bit shifts or multiply by a smaller number, and get more accuracy.Lombard
My bad. Check out KeQueryTimeIncrement to convert to a time value.Hysteric
@wj32: Except that you can only call that from kernel mode...Lombard
True, but I did say "Check out" the function. Well, it turns out you have the system call NtQueryTimerResolution which returns this exact value (the time increment).Hysteric
@wj32: Nice job finding that! It's undocumented but much less hackish than my solution; I like it! +1 for the comment. :)Lombard
Note: it works for KeQueryTickCount, but I don't know what the relationship is between KeQueryTickCount and the USER_SHARED_DATA structure which your NtGetTickCount64 function uses. CBB doing more disassembling.Hysteric
Another hackish way would be to use NtQuerySystemInformation with SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION and adding up the values...Lombard

© 2022 - 2024 — McMap. All rights reserved.