The limits of sleeping

Testing “Project: Wolowizard [1]” isn't easy, what with dealing with The Protocol Stack From Hell™ and clarifying which optional fields of certain messages are mandatory, further complicated by the fact that some optional mandatory fields are optional if other optional mandatory fields are included, but there's also a feature that if used, means you may not include an optional mandatory field, but if you do, then you need to set another optional optional field.

It's all very confusing.

But while I'm waiting for the first extended test run to finish (24 hours of continous tests), I decided to investigate a particular phenomenon [2] I've noticed when developing the testing program.

We need a way to test various message rates and one of the easiest is somethine like:

>
```
for count = 1 , 1000 do
endpoint:send(msg)
sim.sleep(thepausethatrefreshes)
end
```

If I want to send 10 messages per second, then thepausethatrefreshes will be 0.1 (sleep for a tenth of a second); if I want 1000 messages per second, then thepausethatrefreshes will be 0.001. It's an easy way to dial up or down the number of messages per second sent.

The sim.sleep() function (we're using Lua [3] to script our test scenarios) is really a wrapper around the C function nanosleep(), which, in theory, allows a very fine resolution (to the nanosecond) but in reality is limited to the hardware on the system.

And in my testing, I've found that at best, I can get only about 100 messages per second. I wrote a program [4] to test the limits of nanosleep() and found that on our particular testing platform, the lowest I can go is 0.01 seconds (my Linux system, on the other hand, can go as low as 0.002).

As a second test, I just blasted out messages as fast as possible and was able to get a sustained (that is, actually sent and acknowledged) 1,500 per second (or one every 0.0006 seconds). I have to rethink my approach here. I think what may work is to send groups of messages before pausing a bit.

So, if I wanted to send 1,000 messages per second, I would need to write something like:

>
```
function thousand_per_second()
for pauses = 1,50 do
for msgs = 1 , 20 do
endpoint:send(msg)
end
sim.sleep(0.02)
end
end
```

This sends twenty messages per batch, then pauses 0.02 seconds between batches, to give us approximately 1,000 per second (actually, a bit less due to processing overhead).

[1] /boston/2010/10/11.1

[2] http://video.google.com/videoplay?docid=-4114397127563559102

[3] http://www.lua.org/

[4] /boston/2010/10/21/nanosleep.c

Gemini Mention this post

Contact the author