Interval Timers on Windows

B

Bernard Chan

Hi All,

I am writing a script to generate some packets for RTP stream simulation. As
you may know, RTP requires a more-or-less constant packet rate (and hence
UDP is used), and I will need to generate fixed sized packets at regular
intervals, say 20ms, so that will be around 50 packets per second.

On Linux I have tried a version using Time::HiRes ualarm(). On some of my
Linux systems ualarm() can generate a packet rate that approximates 50Hz
pretty well, and the interval variance is infinitesimal. However, I also
have some systems (mostly Fedora) which seem to exhibit increasingly long
intervals after some seconds for reasons unknown to me.

I would also like to have the script usable on Windows that my peers who
have Windows on their systems can perform some tests. There is no ualarm()
in Time::HiRes on Windows, so I tried another approach. I created a
thread-enabled version of the script. A separate thread is created which
does roughly this:

while ($continue) {
sendPacket();
select(undef, undef, undef, 20/1000);
}

However, I find that the sleep between each packet tends to be slightly
higher than 20ms, so after not many packets it is already arriving slower
than the drain rate at the receiver side.

So, I would like to know, whether I can do anything to improve this on the
Windows side? I don't need microseconds or even nanoseconds granularity.
1ms would be generally good enough, but I would like a cross-platform
(Win+Linux at least) approach.

Any insights will be much appreciated.
 
B

Brian Wakem

Bernard said:
Hi All,

I am writing a script to generate some packets for RTP stream simulation.
As you may know, RTP requires a more-or-less constant packet rate (and
hence UDP is used), and I will need to generate fixed sized packets at
regular intervals, say 20ms, so that will be around 50 packets per second.

On Linux I have tried a version using Time::HiRes ualarm(). On some of my
Linux systems ualarm() can generate a packet rate that approximates 50Hz
pretty well, and the interval variance is infinitesimal. However, I also
have some systems (mostly Fedora) which seem to exhibit increasingly long
intervals after some seconds for reasons unknown to me.

I would also like to have the script usable on Windows that my peers who
have Windows on their systems can perform some tests. There is no ualarm()
in Time::HiRes on Windows, so I tried another approach. I created a
thread-enabled version of the script. A separate thread is created which
does roughly this:

while ($continue) {
sendPacket();
select(undef, undef, undef, 20/1000);
}

However, I find that the sleep between each packet tends to be slightly
higher than 20ms, so after not many packets it is already arriving slower
than the drain rate at the receiver side.


Surely you would need to time sendPacket() and subtract it from the next
delay?
 
M

Martijn Lievaart

Surely you would need to time sendPacket() and subtract it from the next
delay?

Surely time spend in sendPacket is negligible om modern machines?

(I don't really know.I/O and syscalls used to be expensive. Nowadays
machines are so fast that syscalls are fast too and sending a packet
generally means -- I assume -- copying it to some internal buffer and
some pointer fiddling, so that should be very fast).

M4
 
B

Bernard Chan

Martijn said:
Surely time spend in sendPacket is negligible om modern machines?

Thanks for your replies.

Actually I have tried a version making similar adjustments to the delay
before, but there was no noticeable improvements (the packet rate is still
highly fluctuating while tending to be slightly < 50Hz in the long term). In
fact the time lag seems to be even more substantial in this version. This is
the exact code of what I tried:

sub sendPacketThread {
my ($t_s, $t_us);
while ($continue) {
($t_s, $t_us) = (time(), ${[gettimeofday()]}[1]);
sendPacket();
my ($t2_s, $t2_us) = (time(), ${[gettimeofday()]}[1]);
my $workTime = ($t2_s - $t_s)*(10**6) + ($t2_us - $t_us);
($t_s, $t_us) = ($t2_s, $t2_us);
select(undef, undef, undef,
($ptime*1000-$workTime)/(10**6));
}
}

This subroutine is what was immediately called from thread->new(). In the
test, both the sender and receiver are on localhost so there should not be
any packet transit issue.

Therefore, I am wondering whether there are any "real" timers accessible on
Windows Perl that gives a more accurate timer. Some fluctuations of delay
in between individual packets is acceptable, but the long-term rate should
be very close to 50Hz or the receiver side will start to drop each packet
on arrival ...
 
M

Martijn Lievaart

This subroutine is what was immediately called from thread->new(). In
the test, both the sender and receiver are on localhost so there should
not be any packet transit issue.

Perl threading is reasonably slow, and I don't know about the granularity
of taskswitches. Maybe you should test this first without threads to see
if threading itself isn't the issue.

HTH,
M4
 
B

Bernard Chan

Martijn said:
Perl threading is reasonably slow, and I don't know about the granularity
of taskswitches. Maybe you should test this first without threads to see
if threading itself isn't the issue.

The same script with single-threaded ualarm() does not have the same issue
on Linux. The major problem I have is that Windows cannot use it. So I'm
trying to look for a solution for Windows machines.

If I use fork() instead of threading, I cannot share variables between them
(on Windows). Or are there mechanisms for addressing shared variables issue
without threads?

Thanks.
 
B

Bernard Chan

On Tue, 01 May 2007 21:04:26 -0700, (e-mail address removed) wrote:

I was curious about this so I tried this thread model, sending packets
on a time boundry. Virtually no drift, mean stayed on target at %99.98.
Actually I was suprised.

Hello,

Do you have the exact source code? I'm interested in seeing how you got to
get it.

Thanks.

Regards,
Bernard Chan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top