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.


Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan

In reply to Re^4: OT How fast a cpu to overwhelm Time::HiRes by tirwhan
in thread OT How fast a cpu to overwhelm Time::HiRes by zentara

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.