boost::thread dependency on boost::chrono (windows implementation)
Hello, as boost::thread now depends on boost::chrono I have the following questions: In boost::chrono on windows the the steady_clock is implemented via QueryPerformanceCounter. This may lead to wrong results because on some systems QueryPerformanceCounter gives different results on different processors. In our software we encountered theses problems regularly on some customers machines and thus stopped using QueryPerformanceCounter without additional checking. The problem I'm talking about is described as a TODO in boost/chrono/system_clocks.hpp My questions is if functions like boost::thread::timed_join or boost::mutex::timed_wait may have similar problems on hardware where QueryPerformanceCounter gives wrong result. Is there a way (like a preprocessor macro) to have boost::thread use the old implementation independent from boost::chrono? Regards, Christian
On 27/06/13 22:42, Christian Hägele wrote:
Hello,
as boost::thread now depends on boost::chrono I have the following questions:
In boost::chrono on windows the the steady_clock is implemented via QueryPerformanceCounter. This may lead to wrong results because on some systems QueryPerformanceCounter gives different results on different processors. In our software we encountered theses problems regularly on some customers machines and thus stopped using QueryPerformanceCounter without additional checking. The problem I'm talking about is described as a TODO in boost/chrono/system_clocks.hpp
My questions is if functions like boost::thread::timed_join or boost::mutex::timed_wait may have similar problems on hardware where QueryPerformanceCounter gives wrong result. Is there a way (like a preprocessor macro) to have boost::thread use the old implementation independent from boost::chrono?
There's the following, but I'm not sure what the implication of not using chrono is! http://www.boost.org/doc/libs/1_53_0/doc/html/thread/build.html#thread.build... Ben
Am 28.06.2013, 04:29 Uhr, schrieb Ben Pope
There's the following, but I'm not sure what the implication of not using chrono is!
http://www.boost.org/doc/libs/1_53_0/doc/html/thread/build.html#thread.build...
Yes, i knew that but with r84750 the following code was merged into release: #if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_CHRONO #undef BOOST_THREAD_DONT_USE_CHRONO #define BOOST_THREAD_USES_CHRONO #endif That code makes the define BOOST_THREAD_DONT_USE_CHRONO on windows useless. That's why I asked on the mailing list. Regards, Christian
Le 27/06/13 16:42, Christian Hägele a écrit :
Hello,
as boost::thread now depends on boost::chrono I have the following questions: Yes, this is dependency that I have not reached to make optional on Windows.
In boost::chrono on windows the the steady_clock is implemented via QueryPerformanceCounter. This may lead to wrong results because on some systems QueryPerformanceCounter gives different results on different processors. In our software we encountered theses problems regularly on some customers machines and thus stopped using QueryPerformanceCounter without additional checking. The problem I'm talking about is described as a TODO in boost/chrono/system_clocks.hpp
Yes, I remember this comment.
My questions is if functions like boost::thread::timed_join or boost::mutex::timed_wait may have similar problems on hardware where QueryPerformanceCounter gives wrong result. Is there a way (like a preprocessor macro) to have boost::thread use the old implementation independent from boost::chrono?
Unfortunately I don't know how to implement a real steady_clock on windows platform, and I was wondering if it shouldn't be removed. Of course if someone knows how to do it, patches are welcome. Best, Vicente
Am 28.06.2013, 07:42 Uhr, schrieb Vicente J. Botet Escriba
Yes, I remember this comment.
My questions is if functions like boost::thread::timed_join or boost::mutex::timed_wait may have similar problems on hardware where QueryPerformanceCounter gives wrong result. Is there a way (like a preprocessor macro) to have boost::thread use the old implementation independent from boost::chrono?
Unfortunately I don't know how to implement a real steady_clock on windows platform, and I was wondering if it shouldn't be removed. Of course if someone knows how to do it, patches are welcome.
Yes, a real steady_clock on windows is hard to implement. GetTickCount works if a resolution of 16ms is okay. Not even the std::chrono of VC11 works, because it uses the normal system-clock(for details see http://connect.microsoft.com/VisualStudio/feedback/details/753063/c-std-chro... or http://connect.microsoft.com/VisualStudio/feedback/details/753115/steady-clo...). Unfortunately if it is not possible to switch to the old implementation of boost::thread(which doesn't depend on boost::chrono) we can't update to boost 1.54. That is a real blocker for us and I don't see a solution right now. Do I miss something? Are we the only ones who suffer from this problem on windows? Regards, Christian
On 28.6.2013 10:01, Christian Hägele wrote:
Unfortunately if it is not possible to switch to the old implementation of boost::thread(which doesn't depend on boost::chrono) we can't update to boost 1.54. That is a real blocker for us and I don't see a solution right now. Do I miss something? Are we the only ones who suffer from this problem on windows?
Ugh, is this a real show stopper? KB (http://support.microsoft.com/kb/274323) was last updated 2006 and the affected devices date way back, too (IDE/ISA stuff that is mostly legacy today). Don't really think it's smart to check OS API results for every system there is as clearly this is an isolated case. You'd have to maintain the affected PCI devices list, do string matching against the PCI IDs (= APIs provide a multi-line string with IDs and compatible IDs), etc. Get's pretty complicated eventually (do you require Boost.Regex, implement own multi-line string matching, use a naive strcmp solution that is error prone etc.) And then comes the funny part. What do you do when you encounter the leap (what counts as a leap)? Try again (how many times?), try again until things are synchronized again (what is the tolerance?), loop forever? A lot of work & maintenance just to support some old platforms that even MS doesn't deem to be worth fixing. I think this is the real problem: This should've been fixed at the OS level instead of forcing users to drop workaround for some specific HWs. Maybe you should gently try to tell your customers that in order to use newer versions of your software they should upgrade their HW & OS. It's not an easy job, I know, as I deal with the legacy stuff, too :( Imho the next best thing would be to check if Boost.Thread does any prev time < new time asserts (this is the *actual* steady-or-not problem, yes?). I.e. make sure that a leap doesn't crash anything. Sleeping a bit less than expected etc. shouldn't really matter anyway as you're not running a critical real time system. -- Pekka
Unfortunately I don't know how to implement a real steady_clock on windows platform, and I was wondering if it shouldn't be removed. Of course if someone knows how to do it, patches are welcome. [snip] Unfortunately if it is not possible to switch to the old implementation of boost::thread(which doesn't depend on boost::chrono) we can't update to boost 1.54. That is a real blocker for us and I don't see a solution right now. Do I miss something? Are we the only ones who suffer from this problem on windows?
What is supposed to be the case (according to Microsoft) is that unsupported versions of Windows (pre-Vista) can experience QueryPerformanceCounter detachment across processor cores on some (older) AMD chips. Supposedly newer Windows have a list of those AMD chips, and will use HPET instead of TSC on those chips (with a consequent 20x overhead increase). In other words, QueryPerformanceCounter() should have no detachment between CPUs on newer Windows. Does this match your experience? Regarding implementing steady clock on Windows using TSC, it is possible: OS X generates gettimeofday() from TSC, and their implementation is a model implementation of how to do that correctly (keep a per CPU skew count). There is also the option of using HPET directly using a variety of Windows APIs such as timeBeginPeriod() et al (http://msdn.microsoft.com/en-us/library/dd743611(v=vs.85).aspx) . There's a very useful page on Microsecond timers on Windows at http://windowstimestamp.com/description. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
On Friday 28 June 2013 14:57:12 Niall Douglas wrote:
What is supposed to be the case (according to Microsoft) is that unsupported versions of Windows (pre-Vista)
Windows XP is still supported: http://windows.microsoft.com/en-us/windows/end-support-help
What is supposed to be the case (according to Microsoft) is that unsupported versions of Windows (pre-Vista)
Windows XP is still supported:
Sorry, instead of supported I should have used "(mis)feature fixable". They closed fixing misfeatures in XP with SP3 which was in 2008. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
On Fri, Jun 28, 2013 at 7:42 AM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Unfortunately I don't know how to implement a real steady_clock on windows platform, and I was wondering if it shouldn't be removed. Of course if someone knows how to do it, patches are welcome.
I think I have pointed a very long time ago (but I can't find the discussion) that Ogre3D had a steady clock for years. If I remember correctly my message was discussed and waived but I'm not sure what was the reason exactly. Anyway the code is open-source under MIT license so you could get inspired from it: https://bitbucket.org/sinbad/ogre/src/0bba4f7cdb953c083aa9e3e15a13857e0988d4... I've used this code for years without any problem after I hit the issue of processor switches. As you can read, on Windows desktops the query will be done always on one core. I have no clear idea of the implications on performance, but I never had performance problem related to this so far. Joel Lamotte
----- Original Message -----
From: "Klaim - Joël Lamotte"
Unfortunately I don't know how to implement a real steady_clock on windows platform, and I was wondering if it shouldn't be removed. Of course if someone knows how to do it, patches are welcome.
I think I have pointed a very long time ago (but I can't find the discussion) that Ogre3D had a steady clock for years. If I remember correctly my message was discussed and waived but I'm not sure what was the reason exactly. Anyway the code is open-source under MIT license so you could get inspired from it: https://bitbucket.org/sinbad/ogre/src/0bba4f7cdb953c083aa9e3e15a13857e0988d4... I've used this code for years without any problem after I hit the issue of processor switches. As you can read, on Windows desktops the query will be done always on one core. I have no clear idea of the implications on performance, but I never had performance problem related to this so far. Joel Lamotte Hello Joel, Personally I have used QueryPerformanceCounter for years on many systems without issues, provided I implement some code to make sure it only runs on one core. It is when the scheduler switches cores for the thread that does the timing that I ran into problems. I have the following in my code: void Timer_LimitThread() { HANDLE hCurrentProcess = GetCurrentProcess(); DWORD_PTR dwProcessAffinityMask = 0; DWORD_PTR dwSystemAffinityMask = 0; if( GetProcessAffinityMask( hCurrentProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ) != 0 && dwProcessAffinityMask ) { DWORD_PTR dwAffinityMask = ( dwProcessAffinityMask & ((~dwProcessAffinityMask) + 1 ) ); HANDLE hCurrentThread = GetCurrentThread(); if( INVALID_HANDLE_VALUE != hCurrentThread ) { SetThreadAffinityMask( hCurrentThread, dwAffinityMask ); CloseHandle( hCurrentThread ); } } CloseHandle( hCurrentProcess ); } I am not sure whether this actually fixes the problem you describe, but I thought I should at least throw the idea out there. Kind regards, Philip Bennefall
participants (8)
-
Andrey Semashev
-
Ben Pope
-
Christian Hägele
-
Klaim - Joël Lamotte
-
Niall Douglas
-
Pekka Seppänen
-
Philip Bennefall
-
Vicente J. Botet Escriba