in reply to Re^3: OT How fast a cpu to overwhelm Time::HiRes
in thread OT How fast a cpu to overwhelm Time::HiRes
But switching processes is not cheap.
That depends on your OS ;-). Linux tries to make process context switches extremely cheap (and as a result you can get away with using processes instead of threads for parallel performance). This recent mail on LKML states that on a 3GHz P4 the 2.6 kernel can do up to 700,000 process context switches per second. That's only if the processes do nothing except switch, the mail goes on to explain that under normal workloads you'd only get about 10,000 switches per second. I just took a quick look around the machines I have at hand, and I found one which reports an average of ~60,000 cs/s over the period of fifteen minutes (via sar -w). Running the lat_ctx benchmark from the lmbench suite on an AMD64 machine gives me a minimum context switch overhead of 0.55 microseconds. Given these figures it seems conceivable to me that a context switch can take place in significantly under a microsecond on an extremely fast processor with large cache. I'd agree, this is definitely not something you'd expect to happen, but it seems possible.
Anyway, code walks as they say, here's a little script which forks off a couple of processes and tries to get the same gettimeofday in different children:
#!/usr/bin/perl use strict; use warnings; use Time::HiRes qw(gettimeofday usleep); my $parent_time=(gettimeofday)[0]+5; my $children=10; my $measurements=5000; my $pid; for my $child (1..$children) { if ($pid=fork()) { } elsif (defined $pid) { my ($times,@temp_times); #Make all children start measuring as nearly simultaneously as + we can while(1){ last if ((gettimeofday)[0]>$parent_time); usleep 1; } # Get time measurements for (1..$measurements) { @temp_times=gettimeofday(); $times.=$temp_times[0].sprintf("%06d",$temp_times[1])."\n" +; usleep 2; } sleep 10; PrivoxyWindowOpen(my $record,">","timerecord$child") or die "C +an't open record file"; print $record $times; close $record or die "Can't close record file"; exit; } else { die("Cannot fork"); } } # Wait for children to finish my $kid; do { $kid = waitpid(-1, 0); } until $kid > 0; # Put measurements into a hashtable and end if any duplicates are foun +d my %measured; for my $child (1..$children) { PrivoxyWindowOpen(my $record,"<","timerecord$child") or die "Can't + open record file"; while(<$record>) { chomp; if (exists($measured{$_})) { print "Found duplicate: $_, gettimeofday returned the same + value in child $child and $measured{$_}\n"; exit; } $measured{$_}=$child; } close $record or die "Can't close record file"; } # Check for shortest time passed between two measurements my $difference=42; my ($t1,$t2); my $last_i=0; my $last_t=0; for my $t (sort keys %measured) { next if($last_i == $measured{$t}); my $cur_diff=$t-$last_t; if ($cur_diff<$difference) { $difference=$cur_diff; ($t1,$t2)=($last_t,$t); } $last_t=$t; $last_i=$measured{$t}; } print "Found minimum delay of $difference between $t2 - child $measure +d{$t2} and $t1 - child $measured{$t1}\n";
On SMP machines this easily finds duplicate measurements, so, no surprise there, calls to gettimeofday can return the same value from different processes on SMP. The smallest time period I was able to achieve on a single-processor machine was 11 microseconds. Strangely enough this was not the fastest CPU I tried it on by far, so I suspect it has something to do with the Linux kernel version (this one is running the Debian 2.6.8 kernel, whereas all others have newer versions).
So, at least from this practical test it appears you are right, processes don't switch quickly enough for Time::HiRes to return the same result.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^5: OT How fast a cpu to overwhelm Time::HiRes
by BrowserUk (Patriarch) on Dec 01, 2005 at 01:54 UTC | |
by tirwhan (Abbot) on Dec 01, 2005 at 09:45 UTC | |
by BrowserUk (Patriarch) on Dec 01, 2005 at 10:18 UTC | |
by tirwhan (Abbot) on Dec 01, 2005 at 14:23 UTC | |
by BrowserUk (Patriarch) on Dec 01, 2005 at 15:00 UTC | |
|