Brian Candler
5/8/2007 7:57:00 AM
On Tue, May 08, 2007 at 04:28:37PM +0900, eden li wrote:
> It looks like this is a pure #sleep issue and has nothing to do with
> sending data over a socket. If you setup a simple loop and average
> the time sleep actually sleeps, you get the following:
>
> want = 0.008, actual (averaged over 1000 attempts) =
> 0.00800016689300537
> want = 0.01, actual (averaged over 1000 attempts) = 0.0122149839401245
> want = 0.012, want (averaged over 1000 attempts) = 0.0120026016235352
>
> Not exactly sure what's so special about 10ms...
>
> Here's what I ran to produce the output above:
>
> def try(n)
> dt, dc = [0, 0]
> 1_000.times do
> t = Time.now.to_f
> sleep n
> dt += Time.now.to_f - t
> dc += 1
> end
> dt / dc
> end
>
> [0.008, 0.01, 0.012].each do |n|
> puts "want = #{n}, actual (averaged over 1000 attempts) = #{try(n)}"
> end
Regardless of how well Ruby's sleep worked, this would still be inaccurate
because of the time needed to execute the other things in the loop.
Try something like this instead:
def run
t = Time.now.to_f
1_000.times do
yield if block_given?
t += 0.01
interval = t - Time.now.to_f
sleep(interval) if interval > 0 # sleep barfs with negative values
end
end
t1 = Time.now
run { x = x }
t2 = Time.now
puts t2 - t1
Your UDP packets will have a small amount of jitter, which the far end's
jitterbuffer will handle (and if this is going over the Internet, you'll get
a lot more jitter from other sources), but will be sent at an average rate
of one every 10ms.
Brian.