Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-04 23:50, Martin Storsjö 写道: On Tue, 4 May 2021, Liu Hao wrote: 在 2021-05-04 18:03, Christian Franke 写道: Next try attached. Thanks. This patch looks good to me. I may push this one if others don't have objections on it. That patch seems to work for me, thanks! Good, I pushed it. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Tue, 4 May 2021, Liu Hao wrote: 在 5/4/21 2:48 AM, Martin Storsjö 写道: Sure. However in practice, with e.g. code like this: typedef void (*fp)(void); _Atomic fp ptr1 = ((void(*)(void))0); _Atomic fp ptr2 = ((void*)0); Clang accepts ptr1 but errors out on ptr2: https://gcc.godbolt.org/z/3YW6EsGP4 It looks like a bug. As per C standard (N2176, ISO/IEC 9899:2017): ``` 6.3.2.3 Pointers 3 An integer constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant. 67) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. ``` So `(void*)0` is also a /null pointer constant/ and should be implicitly convertible to any pointer, including a function pointer. I reported this as https://bugs.llvm.org/show_bug.cgi?id=50219 now, let's see if it gets any feedback. In practice it shouldn't really matter, because as Jacek points out, we should be able to do without the atomics just fine in practice here. I think I have to disagree on this. Just because something works 'in practice' doesn't mean it is correct in principle. The atomic load-store pair is essential to prevent races in case of multiple threads calling this function concurrently. One may argue that such races are harmless, but they are still undefined behavior, and could cause faults if thread sanitizer is involved. Sure, I don't disagree that it's better to be safe with this. We have tons of code that just update a regular pointer (and for cases where the pointer is the __imp_ pointer, the callers won't use atomic semantics for reading it), but we could at least make the updates of them atomic. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Tue, 4 May 2021, Liu Hao wrote: 在 2021-05-04 18:03, Christian Franke 写道: Next try attached. Thanks. This patch looks good to me. I may push this one if others don't have objections on it. That patch seems to work for me, thanks! // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-04 18:03, Christian Franke 写道: Next try attached. Thanks. This patch looks good to me. I may push this one if others don't have objections on it. If the '__atomic*()' are not used, gcc 10.2.0 -O2 generates the same code. '__ATOMIC_SEQ_CST' would make a difference: the store is done via xchgq instead of movq then. Yes that is why I disrecommend `_Atomic`. Most x86 instructions guarantee only acquire-release memory order. The default (strongest) memory order of `_Atomic` requires the `LOCK` prefix (which is implied by `XCHG` when an operand is RAM) [1]. [1] https://stackoverflow.com/questions/27595595/when-are-x86-lfence-sfence-and-mfence-instructions-required -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Liu Hao wrote: 在 5/4/21 2:48 AM, Martin Storsjö 写道: ... In practice it shouldn't really matter, because as Jacek points out, we should be able to do without the atomics just fine in practice here. Yes, see below. I think I have to disagree on this. Just because something works 'in practice' doesn't mean it is correct in principle. The atomic load-store pair is essential to prevent races in case of multiple threads calling this function concurrently. One may argue that such races are harmless, but they are still undefined behavior, and could cause faults if thread sanitizer is involved. Next try attached. If the '__atomic*()' are not used, gcc 10.2.0 -O2 generates the same code. '__ATOMIC_SEQ_CST' would make a difference: the store is done via xchgq instead of movq then. From 155426b0b237ce1a7ee870199734f1d5e525fba8 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 4 May 2021 11:52:02 +0200 Subject: [PATCH] crt: Increase precision of gettimeofday() if possible. Use GetSystemTimePreciseAsFileTime() if available. Signed-off-by: Christian Franke --- mingw-w64-crt/misc/gettimeofday.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/mingw-w64-crt/misc/gettimeofday.c b/mingw-w64-crt/misc/gettimeofday.c index 50ffcfc7..968f3ed3 100644 --- a/mingw-w64-crt/misc/gettimeofday.c +++ b/mingw-w64-crt/misc/gettimeofday.c @@ -41,8 +41,23 @@ int getntptimeofday (struct timespec *tp, struct timezone *z) } if (tp != NULL) { -GetSystemTimeAsFileTime (&_now.ft); /* 100-nanoseconds since 1-1-1601 */ -/* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 microseconds = 0.125 milliseconds */ +typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME); +static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */; + +/* Set function pointer during first call */ +GetSystemTimeAsFileTime_t get_time = + __atomic_load_n (_p, __ATOMIC_RELAXED); +if (get_time == NULL) { + /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */ + get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress ( +GetModuleHandle ("kernel32.dll"), +"GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */ + if (get_time == NULL) +get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */ + __atomic_store_n (_p, get_time, __ATOMIC_RELAXED); +} + +get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */ _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC;/* seconds since 1-1-1970 */ tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */ -- 2.31.1 ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 5/4/21 2:48 AM, Martin Storsjö 写道: Sure. However in practice, with e.g. code like this: typedef void (*fp)(void); _Atomic fp ptr1 = ((void(*)(void))0); _Atomic fp ptr2 = ((void*)0); Clang accepts ptr1 but errors out on ptr2: https://gcc.godbolt.org/z/3YW6EsGP4 It looks like a bug. As per C standard (N2176, ISO/IEC 9899:2017): ``` 6.3.2.3 Pointers 3 An integer constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant. 67) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. ``` So `(void*)0` is also a /null pointer constant/ and should be implicitly convertible to any pointer, including a function pointer. 1. This is not true in C++. C++ does not allow the latter. 2. `(void*)1` is not implicitly convertible to function pointers; however due to the nature of `void*`, it is implicitly convertible to other object pointers such as `int*`. In practice it shouldn't really matter, because as Jacek points out, we should be able to do without the atomics just fine in practice here. I think I have to disagree on this. Just because something works 'in practice' doesn't mean it is correct in principle. The atomic load-store pair is essential to prevent races in case of multiple threads calling this function concurrently. One may argue that such races are harmless, but they are still undefined behavior, and could cause faults if thread sanitizer is involved. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Mon, 3 May 2021, Jacek Caban wrote: I'd say that we should skip it altogether. Atomic operations seem totally redundant in this case. What would it protect from? It won't prevent multiple GetProcAddress calls - for that we'd need a critical section. Since GetProcAddress will always return the same pointer, setting the static pointer multiple times is harmless. As long as a reader can't observe a state where only e.g. half the pointer is updated, I guess it should be safe yeah. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Mon, 3 May 2021, Liu Hao wrote: 在 2021-05-03 20:52, Martin Storsjö 写道: On Mon, 3 May 2021, Christian Franke wrote: Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) That doesn't work either - clang seems to consider the cast (either implicit or explicit) between a integer or pointer-to-integer and a pointer-to-function as something which isn't a compile time constant, in this context... `0` itself is required to be a null pointer constant (not just `0`, but also any integer constant expression that equals zero, such as `1+1-2`). There is no cast in-between. [1] [1] https://gcc.godbolt.org/z/Kv3edeW1j Sure. However in practice, with e.g. code like this: typedef void (*fp)(void); _Atomic fp ptr1 = ((void(*)(void))0); _Atomic fp ptr2 = ((void*)0); Clang accepts ptr1 but errors out on ptr2: https://gcc.godbolt.org/z/3YW6EsGP4 In practice it shouldn't really matter, because as Jacek points out, we should be able to do without the atomics just fine in practice here. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-03 20:52, Martin Storsjö 写道: On Mon, 3 May 2021, Christian Franke wrote: Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) That doesn't work either - clang seems to consider the cast (either implicit or explicit) between a integer or pointer-to-integer and a pointer-to-function as something which isn't a compile time constant, in this context... `0` itself is required to be a null pointer constant (not just `0`, but also any integer constant expression that equals zero, such as `1+1-2`). There is no cast in-between. [1] [1] https://gcc.godbolt.org/z/Kv3edeW1j -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On 5/3/21 2:52 PM, Martin Storsjö wrote: On Mon, 3 May 2021, Christian Franke wrote: Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) That doesn't work either - clang seems to consider the cast (either implicit or explicit) between a integer or pointer-to-integer and a pointer-to-function as something which isn't a compile time constant, in this context... Alternative: Leave '/* = 0 */' only as a comment. There is no need to set a static variable to 0. That would work. But the overall question remains - we don't really require a C11 compiler for this yet, so use of that kind of atomics is a bit odd overall. If we use it, I think we should have to bump the requirement by explicitly building with -std=gnu11 or something like that. If we go that way, I think we should use C11 atomics for all of it, i.e. replace InterlockedCompareExchangePointer with a C11 equivalent. Or go the other way, and use Interlocked* for both reads and updates of it (and then the variable itself doesn't need to be declared _Atomic, afaik). Or just skip that aspect altogether and just blindly update the pointer variable; that's what's done in every existing case of GetProcAddress lazy loading in mingw-w64-crt. I'd say that we should skip it altogether. Atomic operations seem totally redundant in this case. What would it protect from? It won't prevent multiple GetProcAddress calls - for that we'd need a critical section. Since GetProcAddress will always return the same pointer, setting the static pointer multiple times is harmless. Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-03 20:30, Christian Franke 写道: Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) Alternative: Leave '/* = 0 */' only as a comment. There is no need to set a static variable to 0. Either using `= 0` as the initializer or omitting it should work. I don't prefer one to the other. As for the `_Atomic` thing: Yeah it's C11, and I generally avoid its use (because it implies SEQ_CST order which is too strong). Here it is a pointer to the actual function to be called, and is initialized on demand, to something that is not going to change, so instead of writing ```c GetSystemTimeAsFileTime_t get_time = GetSystemTimeAsFileTime_p; if (get_time == NULL) { get_time = ... /* get the actual function */ InterlockedCompareExchangePointer ((void * volatile *) _p, get_time, NULL); } ``` , write ```c GetSystemTimeAsFileTime_t get_time = __atomic_load_n(_p, __ATOMIC_RELAXED); if (get_time == NULL) { get_time = ... /* get the actual function */ __atomic_store_n(_p, get_time, __ATOMIC_RELAXED); } ``` which is semantically correct, and doesn't introduce any overhead. This works since GCC 7. (If `get_time` pointed to mutable memory, instead of a pair of `__ATOMIC_RELAXED`, `__ATOMIC_CONSUME` and `__ATOMIC_RELEASE` would have to be used instead.) -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Mon, 3 May 2021, Christian Franke wrote: Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) That doesn't work either - clang seems to consider the cast (either implicit or explicit) between a integer or pointer-to-integer and a pointer-to-function as something which isn't a compile time constant, in this context... Alternative: Leave '/* = 0 */' only as a comment. There is no need to set a static variable to 0. That would work. But the overall question remains - we don't really require a C11 compiler for this yet, so use of that kind of atomics is a bit odd overall. If we use it, I think we should have to bump the requirement by explicitly building with -std=gnu11 or something like that. If we go that way, I think we should use C11 atomics for all of it, i.e. replace InterlockedCompareExchangePointer with a C11 equivalent. Or go the other way, and use Interlocked* for both reads and updates of it (and then the variable itself doesn't need to be declared _Atomic, afaik). Or just skip that aspect altogether and just blindly update the pointer variable; that's what's done in every existing case of GetProcAddress lazy loading in mingw-w64-crt. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Martin Storsjö wrote: On Mon, 3 May 2021, Martin Storsjö wrote: On Mon, 3 May 2021, Christian Franke wrote: Liu Hao wrote: 在 2021-05-03 14:49, Martin Storsjö 写道: Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. Oh fair enough, if you would like it, I don't mind applying it either. Attached is a new patch with '_Atomic' and 'intptr_t' as requested. This version actually fails to compile with clang, with errors like these: ../misc/gettimeofday.c:45:74: error: initializer element is not a compile-time constant static _Atomic GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p = NULL; ^~~~ /home/martin/clang-trunk/i686-w64-mingw32/include/time.h:91:14: note: expanded from macro 'NULL' #define NULL ((void *)0) ^~~ It seems like it's impossible to provide an initializer to an _Atomic variable with clang, if it's a function pointer type, while a regular pointer can be initialized just fine that way. Well not actually impossible, but impractical. If you'd use ((GetSystemTimeAsFileTime_t)0) as initializer, instead of NULL (which expands to ((void*)0) ) it does actually seem to work. Would plain '... = 0' without cast also work ? IIRC it should since C89 :-) Alternative: Leave '/* = 0 */' only as a comment. There is no need to set a static variable to 0. ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Mon, 3 May 2021, Martin Storsjö wrote: On Mon, 3 May 2021, Christian Franke wrote: Liu Hao wrote: 在 2021-05-03 14:49, Martin Storsjö 写道: Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. Oh fair enough, if you would like it, I don't mind applying it either. Attached is a new patch with '_Atomic' and 'intptr_t' as requested. This version actually fails to compile with clang, with errors like these: ../misc/gettimeofday.c:45:74: error: initializer element is not a compile-time constant static _Atomic GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p = NULL; ^~~~ /home/martin/clang-trunk/i686-w64-mingw32/include/time.h:91:14: note: expanded from macro 'NULL' #define NULL ((void *)0) ^~~ It seems like it's impossible to provide an initializer to an _Atomic variable with clang, if it's a function pointer type, while a regular pointer can be initialized just fine that way. Well not actually impossible, but impractical. If you'd use ((GetSystemTimeAsFileTime_t)0) as initializer, instead of NULL (which expands to ((void*)0) ) it does actually seem to work. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Mon, 3 May 2021, Christian Franke wrote: Liu Hao wrote: 在 2021-05-03 14:49, Martin Storsjö 写道: Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. Oh fair enough, if you would like it, I don't mind applying it either. Attached is a new patch with '_Atomic' and 'intptr_t' as requested. This version actually fails to compile with clang, with errors like these: ../misc/gettimeofday.c:45:74: error: initializer element is not a compile-time constant static _Atomic GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p = NULL; ^~~~ /home/martin/clang-trunk/i686-w64-mingw32/include/time.h:91:14: note: expanded from macro 'NULL' #define NULL ((void *)0) ^~~ It seems like it's impossible to provide an initializer to an _Atomic variable with clang, if it's a function pointer type, while a regular pointer can be initialized just fine that way. If you'd leave out the "= NULL" it should be implicitly initialized to zero as all static variables are, so that should be fine too. But on the other hand, if we're using Interlocked* intrinsics for updating it, we could just as well use an Interlocked* intrinsic for reading it as well (for copying it over to a regular local variable), and then we could do without the variable declared as _Atomic. (FWIW mingw-w64-crt also builds with -std=gnu99, and _Atomic isn't guaranteed to exist until C11 anyway, right?) Also regarding the intptr_t cast, I think it'd be just as fine to cast it directly to the desired destination type without taking it via an intermediate intptr_t here - I see we do that in a number of other places. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Liu Hao wrote: 在 2021-05-03 14:49, Martin Storsjö 写道: Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. Oh fair enough, if you would like it, I don't mind applying it either. Attached is a new patch with '_Atomic' and 'intptr_t' as requested. -- Best regards, Christian Franke From a8d782e5a51deba50f0746080c4f34bb15caf7a7 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Mon, 3 May 2021 13:28:06 +0200 Subject: [PATCH] crt: Increase precision of gettimeofday() if possible. Use GetSystemTimePreciseAsFileTime() if available. Signed-off-by: Christian Franke --- mingw-w64-crt/misc/gettimeofday.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/mingw-w64-crt/misc/gettimeofday.c b/mingw-w64-crt/misc/gettimeofday.c index 50ffcfc7..37dd6556 100644 --- a/mingw-w64-crt/misc/gettimeofday.c +++ b/mingw-w64-crt/misc/gettimeofday.c @@ -41,8 +41,24 @@ int getntptimeofday (struct timespec *tp, struct timezone *z) } if (tp != NULL) { -GetSystemTimeAsFileTime (&_now.ft); /* 100-nanoseconds since 1-1-1601 */ -/* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 microseconds = 0.125 milliseconds */ +typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME); +static _Atomic GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p = NULL; + +/* Set function pointer during first call */ +GetSystemTimeAsFileTime_t get_time = GetSystemTimeAsFileTime_p; +if (get_time == NULL) { + /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */ + get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress ( +GetModuleHandle ("kernel32.dll"), +"GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */ + if (get_time == NULL) +get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */ + /* First thread wins */ + InterlockedCompareExchangePointer ((void * volatile *) _p, +get_time, NULL); +} + +get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */ _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC;/* seconds since 1-1-1970 */ tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */ -- 2.31.1 ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Liu Hao wrote: 在 2021-04-29 03:34, Christian Franke 写道: BTW.2: The *ftime*() functions from newer versions of MSVC CRT also use GetSystemTimePreciseAsFileTime() if available. UCRTBASE.DLL still uses `GetSystemTimeAsFileTime()`. A test program build with VS2019 and estimation of the UCRT source code show that 'GetSystemTimePreciseAsFileTime()' is used if available. It does not even have an entry for the precise one in its import directory table. Yes - this makes the DLL backward compatible with Win7. ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-03 14:49, Martin Storsjö 写道: Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. Oh fair enough, if you would like it, I don't mind applying it either. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Wed, 28 Apr 2021, Liu Hao wrote: 在 4/27/21 2:00 AM, Christian Franke 写道: Which complexity do you mean - the extra cost of the system call or the extra 15 lines of code? Just for the record - I wouldn't mind applying the patch or something like it. I agree with the arguments that it would be beneficial to get more precision here, even if one in general maybe can argue that we don't strictly need to provide such precision. There are also some issues in this patch. You can't assign a `void*` to a pointer-to-function. We have lots of cases of wrappers that do GetProcAddress() in mingw-w64-crt, and a lot of them use a plain (void*) cast. (Others do cast the return value of GetProcAddress() directly to the type of the function pointer.) And you can't use `volatile` variables for synchronization; you have to use `_Atomic` which yet adds more complexity in code. FWIW lots of similar existing cases in mingw-w64-crt just use a plain global pointer that is overwritten, without any atomicity. Just grep for GetProcAddress in mingw-w64-crt and look at all the existing cases. Many of them go via an __MINGW_IMP_SYMBOL pointer which first points at an init function, which then updates the __MINGW_IMP_SYMBOL pointer - but that's essentially the same as here even though this is a static pointer and used inline in a different function. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-05-03 00:39, Dan Raymond 写道: I don't agree with this. First: precision and accuracy are two entirely different things so it's important not to use them interchangeably. It is true that the absolute value of the wall clock time is not likely to be very accurate. If you are interested in the absolute value then increasing precision in clock_gettime() is not going to help you. But if you are interested in the relative difference between two consecutive wall clock times then high precision is useful. Log timestamps are an excellent example of this. I probably won't care if event 1 happened at exactly 10:28:16.594. However I will likely care very much about the precision of the interval between event 1 and event 2. I don't understand your claim that only the order of writes matters in logs. If that were true then we wouldn't use timestamps at all. Yes, you are right, and should one prefer `system_clock`, `steady_clock` or `high_resolution_clock` under such circumstances? Why not call `GetSystemTimePreciseAsFileTime()` directly? -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
1. `clock_gettime()` is not meant to be precise, and it shouldn't be, because the extra accuracy is useless. (It may make some sense for logging, as mentioned in another message; but in logs only the order of writes matters, while timestamps don't matter.) I don't agree with this. First: precision and accuracy are two entirely different things so it's important not to use them interchangeably. It is true that the absolute value of the wall clock time is not likely to be very accurate. If you are interested in the absolute value then increasing precision in clock_gettime() is not going to help you. But if you are interested in the relative difference between two consecutive wall clock times then high precision is useful. Log timestamps are an excellent example of this. I probably won't care if event 1 happened at exactly 10:28:16.594. However I will likely care very much about the precision of the interval between event 1 and event 2. I don't understand your claim that only the order of writes matters in logs. If that were true then we wouldn't use timestamps at all. ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-04-29 03:34, Christian Franke 写道: BTW.2: The *ftime*() functions from newer versions of MSVC CRT also use GetSystemTimePreciseAsFileTime() if available. UCRTBASE.DLL still uses `GetSystemTimeAsFileTime()`. It does not even have an entry for the precise one in its import directory table. A detour via 'intptr_t' would also help but might be considered as ugly as 'void *': get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress (...) This the preferred way if there is no way to get rid of such warnings. See ebd3e57603879490. Several issues accumulate here: - The Mingw-w64 implementations of 'gettimeofday()' and 'clock_gettime(CLOCK_REALTIME,...)' provide only 1/64s resolution. - Mingw-w64 libstdc++ packages are usually configured with _GLIBCXX_USE_GETTIMEOFDAY set and _GLIBCXX_USE_CLOCK_REALTIME and ..._MONOTONIC unset. - Libstdc++ sets 'using high_resolution_clock = system_clock'. This should be configurable. As a consequence, the steady_clock is not steady and the high_resolution_clock has no high resolution. 1. `clock_gettime()` is not meant to be precise, and it shouldn't be, because the extra accuracy is useless. (It may make some sense for logging, as mentioned in another message; but in logs only the order of writes matters, while timestamps don't matter.) 2. That's arguable. The C++ standard says 'high_resolution_clock may be a synonym for system_clock or steady_clock' so it is neither suitable for measurement, nor guaranteed to be convertible to a human-readable date-time string such as `2021-05-02 01:02:03.456`. libstdc++ is not non-conforming, but I think it is not good enough. I suggest you send a patch to GCC so libstdc++ calls `QueryPerformanceCounter()` for `high_resolution_clock`. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Vincent Torri wrote: On Wed, Apr 28, 2021 at 9:35 PM Christian Franke <...> wrote: BTW.1: Hack: Do this once in the program #ifdef _WIN32 timeBeginPeriod(1); https://docs.microsoft.com/fr-fr/windows/win32/api/timeapi/nf-timeapi-timebeginperiod?redirectedfrom=MSDN "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. High resolutions can also prevent the CPU power management system from entering power-saving modes. " The name "Multimedia" (IIRC a marketing term from last millennium) suggests that this API is very old. I'm sure that there was a significant effect with the 60-300Mhz single core CPUs from these days. A quick test with a 10 year old i7-2600K (4C/8T), Win10, idle desktop, OpenHardwareMonitor: During [timeBeginPeriod(1)...timeEndPeriod(1)], CPU Package Power (~7.5W) increased by ~1W, VCore (~0.75V) increased by ~0.10V and Core Clocks (1600MHz) did not change. -- Best regards, Christian Franke ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Corinna Vinschen wrote: On Apr 26 20:00, Christian Franke wrote: System calls and resolutions of C++11 clocks: Mingw-w64 MSVC16 Cygwin system_clock::now() 1 2 2 steady_clock::now() 1 3 3 high_resolution_clock::now() 1 3 3 where 1: GetSystemTimeAsFileTime: >15ms to 1ms (unpredictable) 2: GetSystemTimePreciseAsFileTime: <1us 3: QueryPerformanceCounter: <500ns Not quite. Newer Windows versions support better alternatives compared to QueryPerformanceCounter. Thus on newer systems Cygwin uses QueryUnbiasedInterruptTimePrecisefor CLOCK_MONOTONIC{_RAW} QueryUnbiasedInterruptTime for CLOCK_MONOTONIC_COARSE QueryInterruptTimePrecisefor CLOCK_BOOTTIME{_ALARM} Thanks for chiming in. I obviously forgot to look at Cygwin's current clock.cc :-) and, of course GetSystemTimePreciseAsFileTime for CLOCK_REALTIME GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE Apart from style issues, I vote for using GetSystemTimePreciseAsFileTime for CLOCK_REALTIME and only fall back to GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE or if the OS doesn't support the precise call. +1 from me. Please do keep in mind that there are assumptions of a minimum precision of gettimeofday in the wild, which are not really in our hands. If we can avoid upstream code to #ifdef time computations for Mingw separately, rather than just using gettimeofday on all supported platforms, it's certainly a win-win, isn't it? I agree. The reason for this patch: I searched for a timer with ~1ms resolution for ioctl() duration measurement in debug output of smartmontools. It should work without any #ifdef with Cygwin, MinGW-w64, MSVC16, Linux, *BSD, ... All three C++11 std::chrono clocks could be used, with MinGW-w64 as the only exception. MinGW-w64 uses gettimeofday() for these clocks. -- Best regards, Christian Franke ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Wed, Apr 28, 2021 at 9:35 PM Christian Franke wrote: > > Liu Hao wrote: > > 在 4/27/21 2:00 AM, Christian Franke 写道: > >> > >> Which complexity do you mean - the extra cost of the system call or > >> the extra 15 lines of code? > >> > > > > It's actually both. > > > > Wall clocks are not meant to be steady, because they are free to jump > > back and forth due to NTP synchronization, and arithmetic operations > > aren't predicable either due to leap seconds. > > That's all correct. But there are several use cases where a higher than > this ~15.6ms (1/64s) resolution is needed and where occasional clock > jumps are acceptable - for example debug logs. > > If there were no use cases, the evolution >time() -> ftime(...) -> gettimeofday(...) -> > clock_gettime(CLOCK_REALTIME,...) > would possibly never have happened :-) > > BTW.1: Hack: > Do this once in the program >#ifdef _WIN32 > timeBeginPeriod(1); https://docs.microsoft.com/fr-fr/windows/win32/api/timeapi/nf-timeapi-timebeginperiod?redirectedfrom=MSDN "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. High resolutions can also prevent the CPU power management system from entering power-saving modes. " also, just for more information about this discussion: https://devblogs.microsoft.com/oldnewthing/20170921-00/?p=97057 Vincent Torri ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Liu Hao wrote: 在 4/27/21 2:00 AM, Christian Franke 写道: Which complexity do you mean - the extra cost of the system call or the extra 15 lines of code? It's actually both. Wall clocks are not meant to be steady, because they are free to jump back and forth due to NTP synchronization, and arithmetic operations aren't predicable either due to leap seconds. That's all correct. But there are several use cases where a higher than this ~15.6ms (1/64s) resolution is needed and where occasional clock jumps are acceptable - for example debug logs. If there were no use cases, the evolution time() -> ftime(...) -> gettimeofday(...) -> clock_gettime(CLOCK_REALTIME,...) would possibly never have happened :-) BTW.1: Hack: Do this once in the program #ifdef _WIN32 timeBeginPeriod(1); #endif or start another program which does: Playback a video, run a VM in VBox, run VS 2019, ... ... and the resolution of GetSystemTimeAsFileTime() increases from 1/64s to 1-2ms. BTW.2: The *ftime*() functions from newer versions of MSVC CRT also use GetSystemTimePreciseAsFileTime() if available. Introduction of more overhead upon each call, for some unpredictable and unreliable accuracy, is futile. I guess then it is not worth the effort to provide a related patch for clock_gettime(CLOCK_REALTIME, ...) ?-) There are also some issues in this patch. You can't assign a `void*` to a pointer-to-function. The 'void *' was a hack to silence this warning from gcc 10.2.0: get_time = (GetSystemTimeAsFileTime_t) GetProcAddress (...) "warning: cast between incompatible function types from ‘FARPROC’ {aka ‘long long int (*)()’} to ‘void (*)(struct _FILETIME *)’ [-Wcast-function-type]" A detour via 'intptr_t' would also help but might be considered as ugly as 'void *': get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress (...) And you can't use `volatile` variables for synchronization; you have to use `_Atomic` which yet adds more complexity in code. That's right, in theory, 'volatile' would still allow to read the pointer in two halves or so. Using '_Atomic' instead actually changes the code generated by gcc 10.2.0 -O2, but only few register assignments but no memory accesses. AFAICS, my patch would switch the Mingw-w64 column to '2'. BTW: None of the above provide an extra high_resolution_clock: GNU Libstdc++ Headers: using high_resolution_clock = system_clock; Cygwin (Clang headers), MSVC16: using high_resolution_clock = steady_clock; `high_resolution_clock` should call `QueryPerformanceCounter()` on Windows or `clock_gettime()` on POSIX systems. `gettimeofday()` is apparently not an option, as it is not suitable for measurement. The libstdc++ implementation should be considered faulty. I suggest people avoid its use. Several issues accumulate here: - The Mingw-w64 implementations of 'gettimeofday()' and 'clock_gettime(CLOCK_REALTIME,...)' provide only 1/64s resolution. - Mingw-w64 libstdc++ packages are usually configured with _GLIBCXX_USE_GETTIMEOFDAY set and _GLIBCXX_USE_CLOCK_REALTIME and ..._MONOTONIC unset. - Libstdc++ sets 'using high_resolution_clock = system_clock'. This should be configurable. As a consequence, the steady_clock is not steady and the high_resolution_clock has no high resolution. - Defining _GLIBCXX_USE_CLOCK_MONOTONIC would fix the steady_clock. Drawback: Without '-static', the 'libwinpthreads-1.dll' is required. - And then 'using high_resolution_clock = steady_clock' would fix the high_resolution clock. Drawback: same as above + fix is outside Mingw-w64 source tree. -- Best regards, Christian Franke ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
https://github.com/expnkx/fast_io/blob/725695664091bc4e8fbb05df446aaad93642bbf5/include/fast_io_hosted/time.h#L406 This is my implementation for clock_gettime Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10 From: Corinna Vinschen<mailto:vinsc...@redhat.com> Sent: Wednesday, April 28, 2021 15:05 To: mingw-w64-public@lists.sourceforge.net<mailto:mingw-w64-public@lists.sourceforge.net> Subject: Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible. On Apr 26 20:00, Christian Franke wrote: > System calls and resolutions of C++11 clocks: > >Mingw-w64 MSVC16 Cygwin > system_clock::now() 12 2 > steady_clock::now() 13 3 > high_resolution_clock::now() 13 3 > > where > 1: GetSystemTimeAsFileTime: >15ms to 1ms (unpredictable) > 2: GetSystemTimePreciseAsFileTime: <1us > 3: QueryPerformanceCounter: <500ns Not quite. Newer Windows versions support better alternatives compared to QueryPerformanceCounter. Thus on newer systems Cygwin uses QueryUnbiasedInterruptTimePrecise for CLOCK_MONOTONIC{_RAW} QueryUnbiasedInterruptTimefor CLOCK_MONOTONIC_COARSE QueryInterruptTimePrecise for CLOCK_BOOTTIME{_ALARM} and, of course GetSystemTimePreciseAsFileTimefor CLOCK_REALTIME GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE Apart from style issues, I vote for using GetSystemTimePreciseAsFileTime for CLOCK_REALTIME and only fall back to GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE or if the OS doesn't support the precise call. Please do keep in mind that there are assumptions of a minimum precision of gettimeofday in the wild, which are not really in our hands. If we can avoid upstream code to #ifdef time computations for Mingw separately, rather than just using gettimeofday on all supported platforms, it's certainly a win-win, isn't it? Corinna ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
On Apr 26 20:00, Christian Franke wrote: > System calls and resolutions of C++11 clocks: > > Mingw-w64 MSVC16 Cygwin > system_clock::now() 1 2 2 > steady_clock::now() 1 3 3 > high_resolution_clock::now() 1 3 3 > > where > 1: GetSystemTimeAsFileTime: >15ms to 1ms (unpredictable) > 2: GetSystemTimePreciseAsFileTime: <1us > 3: QueryPerformanceCounter: <500ns Not quite. Newer Windows versions support better alternatives compared to QueryPerformanceCounter. Thus on newer systems Cygwin uses QueryUnbiasedInterruptTimePrecise for CLOCK_MONOTONIC{_RAW} QueryUnbiasedInterruptTimefor CLOCK_MONOTONIC_COARSE QueryInterruptTimePrecise for CLOCK_BOOTTIME{_ALARM} and, of course GetSystemTimePreciseAsFileTimefor CLOCK_REALTIME GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE Apart from style issues, I vote for using GetSystemTimePreciseAsFileTime for CLOCK_REALTIME and only fall back to GetSystemTimeAsFileTime for CLOCK_REALTIME_COARSE or if the OS doesn't support the precise call. Please do keep in mind that there are assumptions of a minimum precision of gettimeofday in the wild, which are not really in our hands. If we can avoid upstream code to #ifdef time computations for Mingw separately, rather than just using gettimeofday on all supported platforms, it's certainly a win-win, isn't it? Corinna ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 4/27/21 2:00 AM, Christian Franke 写道: Which complexity do you mean - the extra cost of the system call or the extra 15 lines of code? It's actually both. Wall clocks are not meant to be steady, because they are free to jump back and forth due to NTP synchronization, and arithmetic operations aren't predicable either due to leap seconds. Introduction of more overhead upon each call, for some unpredictable and unreliable accuracy, is futile. There are also some issues in this patch. You can't assign a `void*` to a pointer-to-function. And you can't use `volatile` variables for synchronization; you have to use `_Atomic` which yet adds more complexity in code. AFAICS, my patch would switch the Mingw-w64 column to '2'. BTW: None of the above provide an extra high_resolution_clock: GNU Libstdc++ Headers: using high_resolution_clock = system_clock; Cygwin (Clang headers), MSVC16: using high_resolution_clock = steady_clock; `high_resolution_clock` should call `QueryPerformanceCounter()` on Windows or `clock_gettime()` on POSIX systems. `gettimeofday()` is apparently not an option, as it is not suitable for measurement. The libstdc++ implementation should be considered faulty. I suggest people avoid its use. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
Liu Hao wrote: 在 2021-04-22 20:35, Christian Franke 写道: This patch significantly increases the precision of gettimeofday() on Windows 8 or later. It is then similar to Cygwin or Linux. It also affects C++11 std::chrono:*_clock as _GLIBCXX_USE_GETTIMEOFDAY is defined but not _GLIBCXX_USE_CLOCK_*. A similar change (or a call to getntptimeofday()) would possibly also make sense for clock_gettime(CLOCK_REALTIME,...). Drawback: GetSystemTimePreciseAsFileTime() is slower than the legacy function. But it is still reasonably fast. Average time per call on an old machine with i7-2600K: GetSystemTimePreciseAsFileTime(): 23ns GetSystemTimeAsFileTime(): <3ns I don't think the complexity is worth. Which complexity do you mean - the extra cost of the system call or the extra 15 lines of code? If users want precision they should use a monotonic clock such as `QueryPerformanceCounter()`. I can't think of any real usage of `gettimeofday()` which needs accurate results. - The API of gettimeofday() provides microsecond precision. - All other gettimeofday() implementations I tested (Cygwin, Linux, FreeBSD, ...) provide a resolution better than 1 millisecond. - GetSystemTimePreciseAsFileTime() combines high resolution with wall-clock accuracy for long term measurements, QueryPerformanceCounter() does not. - The resolution of GetSystemTimeAsFileTime() may change unpredictably between >15ms to 1ms because it depends on the minimum of all current "Multimedia Timer" resolutions (timeBegin/EndPeriod()). - This problem is inherited to all C++11 std::chrono::*clock, in particular high_resolution_clock - which definitely is an indirect usage of gettimeofday() where high resolution is expected. System calls and resolutions of C++11 clocks: Mingw-w64 MSVC16 Cygwin system_clock::now() 1 2 2 steady_clock::now() 1 3 3 high_resolution_clock::now() 1 3 3 where 1: GetSystemTimeAsFileTime: >15ms to 1ms (unpredictable) 2: GetSystemTimePreciseAsFileTime: <1us 3: QueryPerformanceCounter: <500ns AFAICS, my patch would switch the Mingw-w64 column to '2'. BTW: None of the above provide an extra high_resolution_clock: GNU Libstdc++ Headers: using high_resolution_clock = system_clock; Cygwin (Clang headers), MSVC16: using high_resolution_clock = steady_clock; -- Best regards, Christian Franke ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: Increase precision of gettimeofday() if possible.
在 2021-04-22 20:35, Christian Franke 写道: This patch significantly increases the precision of gettimeofday() on Windows 8 or later. It is then similar to Cygwin or Linux. It also affects C++11 std::chrono:*_clock as _GLIBCXX_USE_GETTIMEOFDAY is defined but not _GLIBCXX_USE_CLOCK_*. A similar change (or a call to getntptimeofday()) would possibly also make sense for clock_gettime(CLOCK_REALTIME,...). Drawback: GetSystemTimePreciseAsFileTime() is slower than the legacy function. But it is still reasonably fast. Average time per call on an old machine with i7-2600K: GetSystemTimePreciseAsFileTime(): 23ns GetSystemTimeAsFileTime(): <3ns I don't think the complexity is worth. If users want precision they should use a monotonic clock such as `QueryPerformanceCounter()`. I can't think of any real usage of `gettimeofday()` which needs accurate results. -- Best regards, Liu Hao OpenPGP_signature Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public