date_time clocks, microsec_clock, etc
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, I'm a little curious whats in the works for date_time clock support. Specifically, there still doesn't seem to be anything better than a second-granularity clock for Win32. In addition, the UNIX clock is not always as precise as it could be. In particular, the popular Pentium and and some other architectures have some sorts of cycle-granularity hardware clock or similar that can exceed the usual operating system clock used for time. Really--and I have no idea what work is presently being done on this--it might do people in some problem domains (including myself, at times) a lot of good to have clocks with separate notions of precision and accuracy. For example, on a Pentium, operating systems I care about tend to have a maximum system clock accuracy around about a millisecond plus or minus some, and its probably difficult or tricky to get better than that. However, if the system clock was used in combination with the Pentium cycle counter, we could probably get precision in excess of a nanosecond. Perhaps an interface for such a clock system might be: typedef boost::date_time::clock<type_of_accuracy_you_need_here, type_of_precision_you_need_here> myclock; To get the above imagined clock, I might use: clock<microsecond_accuracy, cycle_precision> If the clock requested was unavailable on the platform, a compile time error might result. Of course, oftentimes we know the characteristics of a clock's accuracy or precision, such as the Pentium cycle counter, but we don't know exactly how precise it is, so it might be inappropriate to refer to that clock as nanosecond_precision when it really might not be. In summary, a reliable cross-platform sub second clock is one of the features I miss most in date_time, and one of the features I can afford to miss least. Is anyone working on remedying this right now? Aaron W. LaFramboise OpenPGP fingerprint: CFB4 D883 17ED E9BE 6F16 1BF7 969F E586 75AC 33C4 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFAlZuhxDYk2wAn5+8RAg5jAJ0XINhLFb4KikH+oK286PQfu6iMaQCgnTe5 SlmNLXTitPUWuUYMKrHIQgY= =bJvg -----END PGP SIGNATURE-----
On Sun, 02 May 2004 20:08:49 -0500, Aaron W. LaFramboise wrote
I'm a little curious whats in the works for date_time clock support. Specifically, there still doesn't seem to be anything better than a second-granularity clock for Win32.
It depends on which compiler you use on Win32. Those that support a posix interface (eg gcc on cygwin). I think Borland and some other might as well. But yes, there should probably be a Win32 version that uses file time.
In addition, the UNIX clock is not always as precise as it could be. In particular, the popular Pentium and and some other architectures have some sorts of cycle-granularity hardware clock or similar that can exceed the usual operating system clock used for time.
Ok.
Really--and I have no idea what work is presently being done on this--it might do people in some problem domains (including myself, at times) a lot of good to have clocks with separate notions of precision and accuracy. For example, on a Pentium, operating systems I care about tend to have a maximum system clock accuracy around about a millisecond plus or minus some, and its probably difficult or tricky to get better than that.
The 'microsec_time_clock' class uses gettimeofday -- an interface that can support up to microsecond resolution. Of course if the clock isn't that accurate, the results won't be either.
However, if the system clock was used in combination with the Pentium cycle counter, we could probably get precision in excess of a nanosecond.
With what algorithm would we achieve this? It's not obvious to me how this would work...
Perhaps an interface for such a clock system might be: typedef boost::date_time::clock<type_of_accuracy_you_need_here, type_of_precision_you_need_here> myclock; To get the above imagined clock, I might use: clock<microsecond_accuracy, cycle_precision>
If the clock requested was unavailable on the platform, a compile time error might result.
Sure we could do something like that, but it might be simplier to have a few predefined types that work commonly.
Of course, oftentimes we know the characteristics of a clock's accuracy or precision, such as the Pentium cycle counter, but we don't know exactly how precise it is, so it might be inappropriate to refer to that clock as nanosecond_precision when it really might not be.
In summary, a reliable cross-platform sub second clock is one of the features I miss most in date_time, and one of the features I can afford to miss least. Is anyone working on remedying this right now?
Not explicitly, but I'm willing to work with you or anyone else on this. One of the core design principles of date_time is that it should be easy to add a new clock without altering the core temporal types. If you take a look at boost/date_time/microsec_time_clock.hpp you can see it isn't that difficult to adapt an API to provide the time. The main issue is figuring out which API to use and how to adapt it into providing the current a yyyy-mm-dd hh:mm:ss.fraction_seconds information. Jeff
I have prototype implementations for a few simple Windows clocks I have in mind in works. I'll post when I get a chance to finish something. In the meantime, perhaps this might be interesting to someone. I wrote this two days ago to assess the capabilities of the clocks on Windows to determine what might be the most suitable as a time source. It outputs a combination of hardcoded information about the documented capabilities of clocks, plus information it has determined real-time about the capabilities of clocks from the OS. It should be standard C++ with documented Windows extensions. I tested on GCC, but it would probably work for any Windows compiler with little or no modifications. The rdtsc support will only work on GCC, though. Note that the implementation is very naïve, and there are probably numerous flaws. Its the best I could come up with without wasting a whole lot of time. I am certainly interested in possible improvements. It takes about 30 seconds to run. On my platform (Windows XP Professional, GCC 3.3.2, MSVCRT runtime, Intel Pentium 4 1.4GHz), it has the following output. I don't have access to a whole lot of other machines presently, so if you have a Windows computer where these tests show interesting results, I would certainly be interested in privately seeing the output on your machine. Measuring timer precision for all system timers. Standard C time() Granularity: 1 second Precision: 1 second Apparent precision: 1 seconds Apparent jitter: 0 seconds Standard C clock() Granularity: Unknown Precision: "implementation's best approximation to processor time" Apparent precision: 0.01 seconds Apparent jitter: 0 seconds Windows system time GetSystemTime() Granularity: 100 nanoseconds Precision: approximately 10 milliseconds (Approximately 55ms on Windows 95/98/ME, 15ms on Windows NT 3.1.) (Presently reported as 10.0144 milliseconds.) Apparent precision: 0.010066666666666666 seconds Apparent jitter: 0.00014285714285714287 seconds Windows system time in file time GetSystemTimeAsFileTime() Granularity: 100 nanoseconds Precision: Same as system time Apparent precision: 0.0100144 seconds Apparent jitter: 0 seconds Windows tick counter GetTickCount() Granularity: 1 millisecond Precision: Same as system time Apparent precision: 0.01 seconds Apparent jitter: 0 seconds Windows Multimedia Timer timeGetTime() Granularity: 1 millisecond Precision: 1 millisecond Apparent precision: 0.0016666666666666668 seconds Apparent jitter: 0.00078571428571428575 seconds Windows High-Performance Timer QueryPerformanceCounter() Granularity: Unknown (Presently reported as 2.7936511484001459e-007 seconds.) Precision: Unknown Apparent precision: 1.6948150300294219e-006 seconds Apparent jitter: 3.9909302120002083e-008 seconds Pentium Timestamp Counter RDTSC Granularity: Unknown (Presently reported as 7.1643876564487315e-010 seconds.) Precision: Same as granularity Apparent precision: 1.2513797106597118e-007 seconds Apparent jitter: 1.5352259263818709e-008 seconds Everything up to the EOF is the source of win32_precision.cpp: const unsigned long iterations = 16; const unsigned long calibrate = 16; #include <cmath> #include <ctime> #include <limits> #include <iomanip> #include <iostream> #include <utility> #include <windows.h> class time_timer { public: void set(); bool operator==(const time_timer &t) const { return time == t.time; } std::time_t operator-(const time_timer &t) const { return time - t.time; } static void warm(); static long double to_seconds(long double); private: std::time_t time; }; void time_timer::set() { time = ::time(0); } void time_timer::warm() { ::time(0); ::time(0); ::time(0); } long double time_timer::to_seconds(long double t) { return t; } class clock_timer { public: void set(); bool operator==(const clock_timer &t) const { return time == t.time; } std::clock_t operator-(const clock_timer &t) const { return time - t.time; } static void warm(); static long double to_seconds(long double); private: std::clock_t time; }; void clock_timer::set() { time = ::clock(); } void clock_timer::warm() { ::clock(); ::clock(); ::clock(); } long double clock_timer::to_seconds(long double t) { return t/CLOCKS_PER_SEC; } class systemtime_timer { public: void set(); bool operator==(const systemtime_timer &t) const { return time.wYear == t.time.wYear && time.wMonth == t.time.wMonth && time.wDayOfWeek == t.time.wDayOfWeek && time.wDay == t.time.wDay && time.wHour == t.time.wHour && time.wMinute == t.time.wMinute && time.wSecond == t.time.wSecond && time.wMilliseconds == t.time.wMilliseconds; } ULONGLONG operator-(const systemtime_timer &t) const { FILETIME a, b; SystemTimeToFileTime(&time, &a); SystemTimeToFileTime(&t.time, &b); return reinterpret_cast<const ULARGE_INTEGER *>(&a)->QuadPart - reinterpret_cast<const ULARGE_INTEGER *>(&b)->QuadPart; } static void warm(); static long double to_seconds(long double); private: SYSTEMTIME time; }; void systemtime_timer::set() { GetSystemTime(&time); } void systemtime_timer::warm() { SYSTEMTIME dummy; GetSystemTime(&dummy); GetSystemTime(&dummy); GetSystemTime(&dummy); } long double systemtime_timer::to_seconds(long double t) { return t/10000000; } class systemtimeaft_timer { public: void set(); bool operator==(const systemtimeaft_timer &t) const { return time.dwLowDateTime == t.time.dwLowDateTime && time.dwHighDateTime == t.time.dwHighDateTime; } ULONGLONG operator-(const systemtimeaft_timer &t) const { return reinterpret_cast<const ULARGE_INTEGER *>(&time)->QuadPart - reinterpret_cast<const ULARGE_INTEGER *>(&t.time)->QuadPart; } static void warm(); static long double to_seconds(long double); private: FILETIME time; }; void systemtimeaft_timer::set() { GetSystemTimeAsFileTime(&time); } void systemtimeaft_timer::warm() { FILETIME dummy; GetSystemTimeAsFileTime(&dummy); GetSystemTimeAsFileTime(&dummy); GetSystemTimeAsFileTime(&dummy); } long double systemtimeaft_timer::to_seconds(long double t) { return t/10000000; } class gettickcount_timer { public: void set(); bool operator==(const gettickcount_timer &t) const { return time == t.time; } DWORD operator-(const gettickcount_timer &t) const { return time - t.time; } static void warm(); static long double to_seconds(long double); private: DWORD time; }; void gettickcount_timer::set() { time = ::GetTickCount(); } void gettickcount_timer::warm() { ::timeGetTime(); ::timeGetTime(); ::timeGetTime(); } long double gettickcount_timer::to_seconds(long double t) { return t/1000; } class timegettime_timer { public: void set(); bool operator==(const timegettime_timer &t) const { return time == t.time; } DWORD operator-(const timegettime_timer &t) const { return time - t.time; } static void warm(); static long double to_seconds(long double); private: DWORD time; }; void timegettime_timer::set() { time = ::timeGetTime(); } void timegettime_timer::warm() { UINT i = 1; for(; i != 100; ++i) { if(timeBeginPeriod(i) != TIMERR_NOCANDO) break; } if(i != 1) std::cerr << "timegettime_timer::warm(): Unable to set timer resolution " "to 1\n"; ::timeGetTime(); ::timeGetTime(); ::timeGetTime(); } long double timegettime_timer::to_seconds(long double t) { return t/1000; } class queryperformance_timer { public: void set(); bool operator==(const queryperformance_timer &t) const { return time.QuadPart == t.time.QuadPart; } LONGLONG operator-(const queryperformance_timer &t) const { return time.QuadPart - t.time.QuadPart; } static void warm(); static long double to_seconds(long double); private: LARGE_INTEGER time; }; void queryperformance_timer::set() { ::QueryPerformanceCounter(&time); } void queryperformance_timer::warm() { LARGE_INTEGER dummy; if(::QueryPerformanceCounter(&dummy) == 0) std::cerr << "timegettime_timer::warm(): System does not support " "high-resolution timer.\n"; ::QueryPerformanceCounter(&dummy); ::QueryPerformanceCounter(&dummy); } long double queryperformance_timer::to_seconds(long double t) { LARGE_INTEGER freq; ::QueryPerformanceFrequency(&freq); return t/freq.QuadPart; } #if defined(__GNUC__) && (defined(__i586__) || defined(__i686__)) __extension__ typedef unsigned long long rdtsc_t; long double cycles_per_second; long double measure_cycles_per_second() { std::time_t last = std::time(0); std::clock_t clock_start = std::clock(); rdtsc_t rdtsc_start; __asm__ __volatile__( "rdtsc" : "=A" (rdtsc_start)); while(std::time(0) != static_cast<std::time_t>(last + calibrate)) {} rdtsc_t rdtsc_stop; __asm__ __volatile__( "rdtsc" : "=A" (rdtsc_stop)); std::clock_t clock_stop = std::clock(); return static_cast<long double>(rdtsc_stop - rdtsc_start) / (clock_stop - clock_start) * CLOCKS_PER_SEC; } class rdtsc_timer { public: void set(); bool operator==(const rdtsc_timer &t) const { return time == t.time; } rdtsc_t operator-(const rdtsc_timer &t) const { return time - t.time; } static void warm(); static long double to_seconds(long double); private: rdtsc_t time; }; void rdtsc_timer::set() { __asm__ __volatile__( "rdtsc" : "=A" (time)); } void rdtsc_timer::warm() { rdtsc_t dummy; __asm__ __volatile__( "rdtsc" : "=A" (dummy)); __asm__ __volatile__( "rdtsc" : "=A" (dummy)); __asm__ __volatile__( "rdtsc" : "=A" (dummy)); } long double rdtsc_timer::to_seconds(long double t) { return t / cycles_per_second; } #endif template<typename timer> std::pair<long double, long double> get_precision() { timer::warm(); timer last; last.set(); long double sum_delta = 0; long double sum_delta_delta = 0; long double last_delta = 0; for(unsigned long i = 0; i != iterations; ++i) { timer now; do { now.set(); } while(now == last); if(i) { long double delta = now - last; sum_delta += delta; if(last_delta) sum_delta_delta += std::fabs(delta - last_delta); last_delta = delta; } last = now; } long double mean = timer::to_seconds(sum_delta/(iterations - 1)); long double jitter = timer::to_seconds(sum_delta_delta/(iterations - 2)); return std::make_pair(mean, jitter); } int main() { std::cout << std::setprecision(std::numeric_limits<long double>::digits10); std::cout << "Measuring timer precision for all system timers.\n\n\n"; std::pair<long double, long double> p; std::cout << "Standard C time()\n" " Granularity: 1 second\n" " Precision: 1 second" << std::endl; p = get_precision<time_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; std::cout << "Standard C clock()\n" " Granularity: Unknown\n" " Precision: \"implementation's best approximation to processor time\"" << std::endl; p = get_precision<clock_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; DWORD adjustment, increment; BOOL disabled; ::GetSystemTimeAdjustment(&adjustment, &increment, &disabled); std::cout << "Windows system time GetSystemTime()\n" " Granularity: 100 nanoseconds\n" " Precision: approximately 10 milliseconds\n" " (Approximately 55ms on Windows 95/98/ME, 15ms on Windows NT 3.1.)\n" " (Presently reported as " << static_cast<long double>(increment)/10000 << " milliseconds.)" << std::endl; p = get_precision<systemtime_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; std::cout << "Windows system time in file time GetSystemTimeAsFileTime()\n" " Granularity: 100 nanoseconds\n" " Precision: Same as system time" << std::endl; p = get_precision<systemtimeaft_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; std::cout << "Windows tick counter GetTickCount()\n" " Granularity: 1 millisecond\n" " Precision: Same as system time" << std::endl; p = get_precision<gettickcount_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; std::cout << "Windows Multimedia Timer timeGetTime()\n" " Granularity: 1 millisecond\n" " Precision: 1 millisecond" << std::endl; p = get_precision<timegettime_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; LARGE_INTEGER freq; ::QueryPerformanceFrequency(&freq); std::cout << "Windows High-Performance Timer QueryPerformanceCounter()\n" " Granularity: Unknown\n" " (Presently reported as " << static_cast<long double>(1)/freq.QuadPart << " seconds.)\n" " Precision: Unknown" << std::endl; p = get_precision<queryperformance_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; #if defined(__GNUC__) && (defined(__i586__) || defined(__i686__)) std::cout << "Pentium Timestamp Counter RDTSC\n" " Granularity: Unknown\n" " (Presently reported as " << std::flush; cycles_per_second = measure_cycles_per_second(); std::cout << static_cast<long double>(1)/cycles_per_second << " seconds.)\n" " Precision: Same as granularity" << std::endl; p = get_precision<rdtsc_timer>(); std::cout << " Apparent precision: " << p.first << " seconds\n" " Apparent jitter: " << p.second << " seconds\n\n"; #endif return 0; } EOF Any comments, let me know. Aaron W. LaFramboise
On Thu, 06 May 2004 02:46:30 -0500, Aaron W. LaFramboise wrote
I have prototype implementations for a few simple Windows clocks I have in mind in works. I'll post when I get a chance to finish something.
Great. BTW, did you see the earlier thread on the boost::timer? There are some pointers to it on the Wiki in case you missed it: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?GDTL/Timer
In the meantime, perhaps this might be interesting to someone. I wrote this two days ago to assess the capabilities of the clocks on Windows to determine what might be the most suitable as a time source. It outputs a combination of hardcoded information about the documented capabilities of clocks, plus information it has determined real-time about the capabilities of clocks from the OS. It should be standard C++ with documented Windows extensions. I tested on GCC, but it would probably work for any Windows compiler with little or no modifications. The rdtsc support will only work on GCC, though.
Note that the implementation is very naïve, and there are probably numerous flaws. Its the best I could come up with without wasting a whole lot of time. I am certainly interested in possible improvements. It takes about 30 seconds to run.
On my platform (Windows XP Professional, GCC 3.3.2, MSVCRT runtime, Intel Pentium 4 1.4GHz), it has the following output. I don't have access to a whole lot of other machines presently, so if you have a Windows computer where these tests show interesting results, I would certainly be interested in privately seeing the output on your machine.
Very interesting. I'll play around with this. If the last 2 measurements are correct they would very precise clocks for timing. Jeff
Jeff Garland wrote:
Very interesting. I'll play around with this. If the last 2 measurements are correct they would very precise clocks for timing.
Yes, except I am very concerned about some things. According to official documentation, QueryPerformanceCounter() does not garentee any particular precision. I'm not entirely sure, in fact, of what timing mechanism it uses myself. In addition, the docs mention that it may not even be implemented. rdtsc is excellent, and I think it has the most potiential of any of the clocks, except that there seems to be some considerable sentiment (Matt Gruenke on this list reminded me of this privately) that it is not terribly reliable as anything other than a cycle counter. In particular, there is rumor of laptops and similar that have the ability to alter their clock frequency runtime. (Compare to QueryPerformanceFrequency, where the documenation garentees the frequency will not change.) Also--I am not sure if this applies to any version of Windows yet or not--the operating system has the ability to completely disable rdtsc, supposedly for use in enforcing security in 'managed' environments. I think Linux does this. This fact somewhat limits the total applicability of rdtsc, especially on future hardware, where rdtsc may be routinely disabled. In both cases, at least in Win32, we can check if they are implemented before we start using them, but then we get this unfortunate situation with names. If a use asks for a nanosec_clock or whatever, but we can't determine until runtime that it isn't availible, what do we do? Throw an exception? Bet they won't be expecting that. Silently use millisec_clock instead? Big difference there. Just some things I am thinking about. Aaron W. LaFramboise
On Thu, 06 May 2004 18:25:32 -0500, Aaron W. LaFramboise wrote
Jeff Garland wrote:
Very interesting. I'll play around with this. If the last 2 measurements are correct they would very precise clocks for timing.
Yes, except I am very concerned about some things.
According to official documentation, QueryPerformanceCounter() does not garentee any particular precision. I'm not entirely sure, in fact, of what timing mechanism it uses myself. In addition, the docs mention that it may not even be implemented.
Ok.
rdtsc is excellent, and I think it has the most potiential of any of the clocks, except that there seems to be some considerable sentiment (Matt Gruenke on this list reminded me of this privately) that it is not terribly reliable as anything other than a cycle counter. In particular, there is rumor of laptops and similar that have the ability to alter their clock frequency runtime. (Compare to QueryPerformanceFrequency, where the documenation garentees the frequency will not change.) Also--I am not sure if this applies to any version of Windows yet or not--the operating system has the ability to completely disable rdtsc, supposedly for use in enforcing security in 'managed' environments. I think Linux does this. This fact somewhat limits the total applicability of rdtsc, especially on future hardware, where rdtsc may be routinely disabled.
Ok.
In both cases, at least in Win32, we can check if they are implemented before we start using them, but then we get this unfortunate situation with names. If a use asks for a nanosec_clock or whatever, but we can't determine until runtime that it isn't availible, what do we do? Throw an exception? Bet they won't be expecting that. Silently use millisec_clock instead? Big difference there.
Well I think this is a case of documenting the environments where the higher resolution clocks / timers may be available. At the compiler OS level we can just fail to compiler if the high resolution is not available. Even if it varies based on the hardware, we should be able to provide a program (such as the one you already wrote) that would allow a user to see how the clocks function in their environment and make a decision about whether they should use them. For those that need something portable we should be able to get microsecond resolution for Windows, Linux, and probably a few more... Jeff
Perhaps we should add a method to each that would return precision/jitter/whathaveyou. that way you don't have to throw an exception or cause any error. OTOH, maybe you want to add an arg that says "at least this good" <shrug> At Thursday 2004-05-06 18:01, you wrote:
On Thu, 06 May 2004 18:25:32 -0500, Aaron W. LaFramboise wrote
Jeff Garland wrote:
Very interesting. I'll play around with this. If the last 2 measurements are correct they would very precise clocks for timing.
Yes, except I am very concerned about some things.
According to official documentation, QueryPerformanceCounter() does not garentee any particular precision. I'm not entirely sure, in fact, of what timing mechanism it uses myself. In addition, the docs mention that it may not even be implemented.
Ok.
rdtsc is excellent, and I think it has the most potiential of any of the clocks, except that there seems to be some considerable sentiment (Matt Gruenke on this list reminded me of this privately) that it is not terribly reliable as anything other than a cycle counter. In particular, there is rumor of laptops and similar that have the ability to alter their clock frequency runtime. (Compare to QueryPerformanceFrequency, where the documenation garentees the frequency will not change.) Also--I am not sure if this applies to any version of Windows yet or not--the operating system has the ability to completely disable rdtsc, supposedly for use in enforcing security in 'managed' environments. I think Linux does this. This fact somewhat limits the total applicability of rdtsc, especially on future hardware, where rdtsc may be routinely disabled.
Ok.
In both cases, at least in Win32, we can check if they are implemented before we start using them, but then we get this unfortunate situation with names. If a use asks for a nanosec_clock or whatever, but we can't determine until runtime that it isn't availible, what do we do? Throw an exception? Bet they won't be expecting that. Silently use millisec_clock instead? Big difference there.
Well I think this is a case of documenting the environments where the higher resolution clocks / timers may be available. At the compiler OS level we can just fail to compiler if the high resolution is not available. Even if it varies based on the hardware, we should be able to provide a program (such as the one you already wrote) that would allow a user to see how the clocks function in their environment and make a decision about whether they should use them.
For those that need something portable we should be able to get microsecond resolution for Windows, Linux, and probably a few more...
Jeff _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"
Aaron,
"Aaron W. LaFramboise" <aaronrabiddog51@aaronwl.com> wrote in message news:4099ED56.6010806@aaronwl.com...
[snip]
Windows system time GetSystemTime() Granularity: 100 nanoseconds Precision: approximately 10 milliseconds (Approximately 55ms on Windows 95/98/ME, 15ms on Windows NT 3.1.) (Presently reported as 10.0144 milliseconds.) Apparent precision: 0.010066666666666666 seconds Apparent jitter: 0.00014285714285714287 seconds
Windows system time in file time GetSystemTimeAsFileTime() Granularity: 100 nanoseconds Precision: Same as system time Apparent precision: 0.0100144 seconds Apparent jitter: 0 seconds
FYI see ::timeBeginPeriod / ::timeEndPeriod to get Precision down near 1ms on WindowsNT/2K/XP. THis also affects ::Sleep. ----------------- Jeff Flinn Applied Dynamics, International
Jeff Flinn wrote:
Windows system time GetSystemTime() Granularity: 100 nanoseconds Precision: approximately 10 milliseconds (Approximately 55ms on Windows 95/98/ME, 15ms on Windows NT 3.1.) (Presently reported as 10.0144 milliseconds.) Apparent precision: 0.010066666666666666 seconds Apparent jitter: 0.00014285714285714287 seconds
Windows system time in file time GetSystemTimeAsFileTime() Granularity: 100 nanoseconds Precision: Same as system time Apparent precision: 0.0100144 seconds Apparent jitter: 0 seconds
FYI see ::timeBeginPeriod / ::timeEndPeriod to get Precision down near 1ms on WindowsNT/2K/XP. THis also affects ::Sleep.
Are you sure? I only thought that affected timeGetTime (and on recent Windows, I think its by default 1ms anyway). The documentation mentions that the precision of the system clock is equal to the frequency of the clock interrupt. The system time is incremented by a particular value (that you can set with SetSystemTimeAdjustment()) each clock interrupt to maintain the clock. In any case, in a quick test, calling timeBeginPeriod doesn't seem to have any affect on the GetSystemTime() and friends. Not sure about Sleep() though. Aaron W. LaFramboise
At Thursday 2004-05-06 00:46, you wrote:
I have prototype implementations for a few simple Windows clocks I have in mind in works. I'll post when I get a chance to finish something.
In the meantime, perhaps this might be interesting to someone. I wrote this two days ago to assess the capabilities of the clocks on Windows to determine what might be the most suitable as a time source. It outputs a combination of hardcoded information about the documented capabilities of clocks, plus information it has determined real-time about the capabilities of clocks from the OS. It should be standard C++ with documented Windows extensions. I tested on GCC, but it would probably work for any Windows compiler with little or no modifications. The rdtsc support will only work on GCC, though.
I try to build it on my system vs.net2003 and I get the following (the warnings aren't the problem, the missing symbols are): ------ Build started: Project: PossibleClockEnhancements, Configuration: Release Win32 ------ Compiling... PossibleClockEnhancements.cpp PossibleClockEnhancements.cpp(400) : warning C4244: 'initializing' : conversion from 'ULONGLONG' to 'long double', possible loss of data PossibleClockEnhancements.cpp(452) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> get_precision<systemtime_timer>(void)' being compiled with [ _Ty1=long double, _Ty2=long double ] PossibleClockEnhancements.cpp(400) : warning C4244: 'initializing' : conversion from 'ULONGLONG' to 'long double', possible loss of data PossibleClockEnhancements.cpp(459) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> get_precision<systemtimeaft_timer>(void)' being compiled with [ _Ty1=long double, _Ty2=long double ] PossibleClockEnhancements.cpp(400) : warning C4244: 'initializing' : conversion from 'LONGLONG' to 'long double', possible loss of data PossibleClockEnhancements.cpp(485) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> get_precision<queryperformance_timer>(void)' being compiled with [ _Ty1=long double, _Ty2=long double ] Linking... PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: static void __cdecl gettickcount_timer::warm(void)" (?warm@gettickcount_timer@@SAXXZ) PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeBeginPeriod@4 referenced in function "public: static void __cdecl timegettime_timer::warm(void)" (?warm@timegettime_timer@@SAXXZ) Release/PossibleClockEnhancements.exe : fatal error LNK1120: 2 unresolved externals Build log was saved at "file://c:\Projects\Programming\Kokopelli Technology\boost_testing\PossibleClockEnhancements\Release\BuildLog.htm" PossibleClockEnhancements - 3 error(s), 3 warning(s) ---------------------- Done ---------------------- Build: 0 succeeded, 1 failed, 0 skipped [deleted] Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"
Victor A. Wagner Jr. wrote:
PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: static void __cdecl gettickcount_timer::warm(void)" (?warm@gettickcount_timer@@SAXXZ) PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeBeginPeriod@4 referenced in function "public: static void __cdecl timegettime_timer::warm(void)" (?warm@timegettime_timer@@SAXXZ) Release/PossibleClockEnhancements.exe : fatal error LNK1120: 2 unresolved externals
Its traditional on Windows to not link against the 'winmm' library by default. You need to add winmm.lib or whatever to the link line. That is one unfortunate downside to using this timer that is otherwise traditionally very well-supported and stable and precise in comparison to the alternatives. Aaron
At Thursday 2004-05-06 21:50, you wrote:
Victor A. Wagner Jr. wrote:
PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: static void __cdecl gettickcount_timer::warm(void)" (?warm@gettickcount_timer@@SAXXZ) PossibleClockEnhancements.obj : error LNK2019: unresolved external symbol __imp__timeBeginPeriod@4 referenced in function "public: static void __cdecl timegettime_timer::warm(void)" (?warm@timegettime_timer@@SAXXZ) Release/PossibleClockEnhancements.exe : fatal error LNK1120: 2 unresolved externals
Its traditional on Windows to not link against the 'winmm' library by default. You need to add winmm.lib or whatever to the link line. That is one unfortunate downside to using this timer that is otherwise traditionally very well-supported and stable and precise in comparison to the alternatives.
you'd _think_ (nah, that's expecting too much of MS) that Microsoft would use a #pragma comment lib blah (or whatever the syntax is) if you used the functions.
Aaron
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"
At Thursday 2004-05-06 00:46, you wrote:
I have prototype implementations for a few simple Windows clocks I have in mind in works. I'll post when I get a chance to finish something.
In the meantime, perhaps this might be interesting to someone. I wrote this two days ago to assess the capabilities of the clocks on Windows to determine what might be the most suitable as a time source. It outputs a combination of hardcoded information about the documented capabilities of clocks, plus information it has determined real-time about the capabilities of clocks from the OS. It should be standard C++ with documented Windows extensions. I tested on GCC, but it would probably work for any Windows compiler with little or no modifications. The rdtsc support will only work on GCC, though.
I added Winmm.lib as an additional dependency to my properties (link) and it now links, sorry for the alarm [deleted] Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"
participants (5)
-
Aaron W. LaFramboise
-
Aaron W. LaFramboise
-
Jeff Flinn
-
Jeff Garland
-
Victor A. Wagner Jr.