|
Home > Archive > Unix Programming > August 2007 > Generating traffic at a specified bitrate
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Generating traffic at a specified bitrate
|
|
|
| Hello everyone,
Consider a recent Linux system (say 2.6.22) with high-resolution timer
support and a GigE interface.
Suppose I want to write an app that sends packets at a specified rate.
L = size of a packet (in bytes)
R = rate (in bytes per second)
T = L/R = inter-packet period (in seconds)
Ideally, the app would send the packets "smoothly" (that is one packet
every T seconds).
For example, if L = 1316 bytes and R = 8 Mbit/s then T = 1.316 ms
The obvious algorithm would be:
while ( 1 )
{
sleep for T;
send one packet;
}
The app might sleep more than T, if the sytem is busy.
One work-around is to use absolute dates.
deadline = current date;
while ( 1 )
{
deadline += T;
sleep until deadline;
send one packet;
}
In my experience, this solution works well when T >= 500 µs
Consider now L = 1316 bytes and R = 800 Mbit/s then T = 13.16 µs
The system might not be able to wake up every 13 µs. As far as I
understand, the OS will arm a hardware timer. When that timer expires,
it will generate an IRQ which the CPU has to service. I'm not sure my
platform (x86) was designed to handle such high IRQ rates.
An option would be to group several packets per iteration. This would
reduce the number of IRQs generated by the timer.
deadline = current date;
while ( 1 )
{
deadline += N*T;
sleep until deadline;
send N packets;
}
For example, when L = 1316 and R = 800 Mbit/s we can pick N = 50
which means we will send 50 packets every 658 µs. Thus the hardware
timer will only generate 1520 IRQs per second instead of 76000. If the
rest of the system can handle 800 Mbit/s, this solution might work for
any specified bitrate. What do you think?
Will network interfaces typically generate one IRQ per packet sent?
Regards.
| |
| Ben Bacarisse 2007-08-30, 1:20 pm |
| Spoon <root@localhost> writes:
> Consider a recent Linux system (say 2.6.22) with high-resolution timer
> support and a GigE interface.
>
> Suppose I want to write an app that sends packets at a specified rate.
<various methods snipped>
> deadline = current date;
> while ( 1 )
> {
> deadline += N*T;
> sleep until deadline;
> send N packets;
> }
>
> For example, when L = 1316 and R = 800 Mbit/s we can pick N = 50
> which means we will send 50 packets every 658 µs. Thus the hardware
> timer will only generate 1520 IRQs per second instead of 76000. If the
> rest of the system can handle 800 Mbit/s, this solution might work for
> any specified bitrate. What do you think?
Rather than specify (or calculate) N, I would keep track of what rate
the loop has managed (by measuring the actual time elapsed and the
number of packets sent) and adjusting the sleep time so as to make
your average rate (averaged over some recent time period) match your
target.
The only time I had to do this (a long time ago) it worked better than
trying to fix the rate up front of the loop. Things may have changed,
now, but I'd lay odds you get the best match to your target rate and
less fussing about what can and can not be serviced doing it this way.
It will fail only when the system simply can't do what is required.
The calculated sleep time will fall to zero and you can bail out then
with a "no can do" error.
--
Ben.
|
|
|
|
|