Daniel McBrearty wrote: > I wrote a script today that started a thread that was polling every > 1000ms. I used > > use Time::HiRes qw( usleep ); > usleep(1000 * 1000); > > I didn't get the stopwatch out, but it looked as if the timing was way > off. As I need to scale to much shorter timings, I need to use this > module. > > Does anyone else have this experience and know why it is so?
Works for me - the longer the time, the more accurate it should be since timers don't have the same resolution that clocks do. I think they're accurate to 10-15 msec on Intel and use message passing which could affect shorter times. You can also use Win32::GetTickCount for a possibly more accurate resolution (not a timer per se). QueryPerformanceCounter / QueryPerformanceFrequency can access an 8 usec counter if avail. I have some code after this snippet that you could try if you need to time a chunk of code accurately - just call start_PC_timer before and stop_PC_timer after. Try this and see what you get (also try varying the time - I'm using 10 secs below): use strict; use warnings; use Time::HiRes qw(usleep); for (1 .. 10) { my $pt0 = Win32::GetTickCount (); usleep ($_ * 1000 * 1000); printf "%.3f seconds\n", (Win32::GetTickCount () - $pt0) / 1000; } __END__ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - use strict; use warnings; use Win32::API; my $QueryPerformanceCounter; # API function obj once set in PC_init my $QueryPerformanceFrequency; # API function obj once set in PC_init my $PC_Freq; # computed performance counter freq in seconds my $QPC_Ovhd; # computed overhead of QPC API call in seconds sub init_PC { # set 4 global vrbls for using timing routines return if $QueryPerformanceCounter; $QueryPerformanceCounter = new Win32::API('kernel32', 'QueryPerformanceCounter', [qw(P)], 'I') or die 'Failed to get QueryPerformanceCounter:', Win32::FormatMessage ( Win32::GetLastError ()); # set global $QueryPerformanceFrequency = new Win32::API('kernel32', 'QueryPerformanceFrequency', [qw(P)], 'I') or die 'Failed to get QueryPerformanceFrequency:', Win32::FormatMessage ( Win32::GetLastError ()); # set global my $Freq = pack 'I2', 0; if (not $QueryPerformanceFrequency->Call($Freq)) { die 'QueryPerformanceFrequency call failed:', Win32::FormatMessage (Win32::GetLastError ()); } my @Freq = reverse unpack 'I2', $Freq; $PC_Freq = $Freq[0] * 2**32 + $Freq[1]; # set global printf "QueryPerformanceCounter freq: 1/%u sec\n\n", $PC_Freq if $debug; $QPC_Ovhd = get_QPC_overhead (); # set global } #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sub get_QPC_overhead { my $Ctr1 = pack 'I2', 0; my $Ctr2 = pack 'I2', 0; if (not $QueryPerformanceCounter->Call($Ctr1)) { die 'QueryPerformanceCounter call failed:', Win32::FormatMessage (Win32::GetLastError ()); } my $max_loops = 100; # adjust down to lower overhead my $total = 0; for (1 .. $max_loops) { $QueryPerformanceCounter->Call($Ctr1); $QueryPerformanceCounter->Call($Ctr2); my @Ctr1 = reverse unpack 'I2', $Ctr1; my @Ctr2 = reverse unpack 'I2', $Ctr2; printf "Start Value: %u, %u\n", $Ctr1[0], $Ctr1[1] if $debug; printf "End Value: %u, %u\n", $Ctr2[0], $Ctr2[1] if $debug; my $diff = ($Ctr2[0] * 2**32 + $Ctr2[1]) - ($Ctr1[0] * 2**32 + $Ctr1[1]); printf "diff: %u / freq: %u = %f\n\n", $diff, $PC_Freq, $diff / $PC_Freq if $debug; $total += $diff; } my $ovhd = $total / $max_loops / $PC_Freq; printf "API Overhead: %.8f seconds\n", $ovhd if $debug; return $ovhd } #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sub start_PC_timer { init_PC (); my $Ctr1 = pack 'I2', 0; $QueryPerformanceCounter->Call($Ctr1); my @Ctr1 = reverse unpack 'I2', $Ctr1; return [EMAIL PROTECTED]; } #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sub stop_PC_timer { my $Ctr1ref = shift; my $Ctr2 = pack 'I2', 0; $QueryPerformanceCounter->Call($Ctr2); my @Ctr2 = reverse unpack 'I2', $Ctr2; my $diff = ($Ctr2[0] * 2**32 + $Ctr2[1]) - ($Ctr1ref->[0] * 2**32 + $Ctr1ref->[1]); my $et = ($diff - $QPC_Ovhd) / $PC_Freq; printf "Elapsed time: %f\n", $et if $debug; return $et; } #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _______________________________________________ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs