if it takes a while to execute; your start times will gradually become offset. For example, if your processing takes 2 minutes and you sleep for 3 hours starting at noon...
If start time drift is a problem, you can stay in sync by simply reading the current time and then calculating how long you want to sleep, in order to wake up at the desired time.
The following snippet does just that. My internal mail server (running Bloatus Notes) has to be shut down for backups. Rather than sending mail (created by other night-time batch jobs) to the external server, I just sleep until a point in time when I know it will be available.
use Time::Local;
# sleep a while until the mail server comes back up
my @later_bits = (localtime)[0..5];
@later_bits[2,1] = (8, 15); # 08:15
my $later = timelocal( @later_bits );
my $duration = $later > $now ? $later - $now : 0;
sleep $duration;
Modifying this to allow for sleeping up until midday modulo 3 is left as an exercise to the reader. Note that this technique lets you do cool stuff like "run every 8 minutes", which is not possible with standard cron.
update: while I do use Paul Vixie's cron when I can, it's not always present. On Solaris, for instance, you can only specify comma-separated values (at least on the O/S version I use at the moment).
I would be hesitant of of using */8 in a crontab entry, because 60 is not evenly divisible by 8. I've never bothered to see what it would do, but I have a sneaking suspicion that it would fire off your script at 0, 8, 16 ... 48 and 56 minutes of the hour. Thus, at the end of the hour the script will have two runs 4 minutes apart.
print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u' |