From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4165 invoked by alias); 29 Sep 2014 21:00:34 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 4098 invoked by uid 48); 29 Sep 2014 21:00:27 -0000 From: "frankhb1989 at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/63400] [C++11]precision of std::chrono::high_resolution_clock Date: Mon, 29 Sep 2014 21:00:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 4.9.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: minor X-Bugzilla-Who: frankhb1989 at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-09/txt/msg02718.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63400 --- Comment #4 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #3) > What libstdc++ is doing is sensible, why is the realtime clock so much > coarser than the monotonic clock on mingw-w64? It is not always true that the real time clock would have a higher resolution than monotonic clock. At least I found nothing about resolution guaranteed by POSIX, in fact, "clock resolutions are implementation-defined". With mingw-w64, the following program shows that the monotonic clock is far more precise: #include #include int main() { using namespace std; timespec ts; if(clock_getres(CLOCK_REALTIME, &ts) == 0) cout << "CLOCK_REALTIME: " << ts.tv_sec << ',' << ts.tv_nsec << endl; if(clock_getres(CLOCK_MONOTONIC, &ts) == 0) cout << "CLOCK_MONOTONIC: " << ts.tv_sec << ',' << ts.tv_nsec << endl; } The result on my machine: CLOCK_REALTIME: 0,15625000 CLOCK_MONOTONIC: 0,489 I then found the actual implementation in winpthreads (clock.c): int clock_gettime(clockid_t clock_id, struct timespec *tp) { unsigned __int64 t; LARGE_INTEGER pf, pc; union { unsigned __int64 u64; FILETIME ft; } ct, et, kt, ut; switch(clock_id) { case CLOCK_REALTIME: { GetSystemTimeAsFileTime(&ct.ft); t = ct.u64 - DELTA_EPOCH_IN_100NS; tp->tv_sec = t / POW10_7; tp->tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } case CLOCK_MONOTONIC: { if (QueryPerformanceFrequency(&pf) == 0) return lc_set_errno(EINVAL); if (QueryPerformanceCounter(&pc) == 0) return lc_set_errno(EINVAL); tp->tv_sec = pc.QuadPart / pf.QuadPart; tp->tv_nsec = (int) (((pc.QuadPart % pf.QuadPart) * POW10_9 + (pf.QuadPart >> 1)) / pf.QuadPart); if (tp->tv_nsec >= POW10_9) { tp->tv_sec ++; tp->tv_nsec -= POW10_9; } return 0; } case CLOCK_PROCESS_CPUTIME_ID: { if(0 == GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft)) return lc_set_errno(EINVAL); t = kt.u64 + ut.u64; tp->tv_sec = t / POW10_7; tp->tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } case CLOCK_THREAD_CPUTIME_ID: { if(0 == GetThreadTimes(GetCurrentThread(), &ct.ft, &et.ft, &kt.ft, &ut.ft)) return lc_set_errno(EINVAL); t = kt.u64 + ut.u64; tp->tv_sec = t / POW10_7; tp->tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } default: break; } return lc_set_errno(EINVAL); } For CLOCK_REALTIME, the Windows API GetSystemTimeAsFileTime is used. GetSystemTimePreciseAsFileTime is an improved version which provide "the highest possible level of precision (<1us)". Unfortunately, the latter is only available since Windows 8/Windows 2012, which is not suited for winpthreads for compatibility reason IMO. See this MSDN page for details: http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx For CLOCK_MONOTONIC, QPC(Query Performance Counter) APIs are used. This method is reasonably portable (among different versions of Windows, since Windows 2000), and Microsoft strongly suggested it when high-resolution time stamps needed, see http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx. However, QPC is not suited for a system-wide clock.