[C++] Win32 Sleep(1) different on multi-core system

Started by
14 comments, last by Evil Steve 16 years, 8 months ago
The 3 common scheduler granularities on windows systems are:

10ms, 15ms, and 55ms

(100hz, 66.6hz, and 18.2hz)

Which one applies depends on several factors, mainly:

OS, and Motherboard.

On Win32 and beyond, it will be 10ms or 15ms by default unless its run on very old hardware.

For the record, its 15ms on my AMD64x2 running XP/64
Advertisement
I'm sorry for reviving the topic again, but I am still struggling with this problem.

Right now, I have a server that sits and polls for messages on udp port. I don't want the server to use up 100% of any core just for that. Introducing Sleep(1) causes the problem where it sleeps for much longer. And 10 ms sleep is not acceptable since it only then allows at best 100 messages/sec. Sleep(0) does nothing in terms of CPU utilization.

Does anyone know of how to accomplish the Sleep(1) but with the side effect of 1 ms pause, at most, not at least. And without using the timeBeingPeriod(1) functionality.

How do services like SQL Server process 1000s of request per second yet use tiny amount of CPU when idle?
Quote:Original post by azherdev
And 10 ms sleep is not acceptable since it only then allows at best 100 messages/sec.


Nope. It allows much more than that, assuming that you do the sane thing and only make the server sleep if there are no more messages (why would you put it to sleep if it still has work to do?)

A simple loop such as the following should provide a good starting point:
while (running){  while (Message m = Poll())    Handle(m);  sleep(1);}


It acts as if the server doesn't sleep whenever there are messages in the UDP queue (ensuring optimal throughput), and acts as if the server always sleeps if there are no messages to be handled (ensuring process nicety). The only downside is that messages will be handled in batches every 10 milliseconds if they are too few to keep the thread working.
Quote:Original post by azherdev
I'm sorry for reviving the topic again, but I am still struggling with this problem.

Right now, I have a server that sits and polls for messages on udp port. I don't want the server to use up 100% of any core just for that. Introducing Sleep(1) causes the problem where it sleeps for much longer. And 10 ms sleep is not acceptable since it only then allows at best 100 messages/sec. Sleep(0) does nothing in terms of CPU utilization.

Does anyone know of how to accomplish the Sleep(1) but with the side effect of 1 ms pause, at most, not at least. And without using the timeBeingPeriod(1) functionality.

What you are asking for specifically (the Sleep(1), but without... etc) is probably impossible.

Quote:Original post by azherdev
How do services like SQL Server process 1000s of request per second yet use tiny amount of CPU when idle?

Short answer:
blocking calls

Long answer:
The keyword in your post that is causing your undesired behaviour is "polls". You do not want polling. Polling is evil.
A socket's receive function can be blocking, and it only falls through when a packet is received. As long as it is blocking it will not use any CPU at all.
So, throw out your polling.
STOP THE PLANET!! I WANT TO GET OFF!!
Unfortunately, the lib I am using (RakNet) only supports "polling" for packets. It doesn't appear to be able to block until packet is received. The other caviat is that certain packet types require polling BUT will not return to you a valid packet because it is processed internally. So even though I did receive a packet and RakNet processed it, I don't get a packet handle back from the polling function. :(

I did update my loop to only Sleep(1) if no packet is received. But again, if there are many of these "hidden" events, I will sleep on them as though no events processed.
Quote:Original post by azherdev
Unfortunately, the lib I am using (RakNet) only supports "polling" for packets. It doesn't appear to be able to block until packet is received. The other caviat is that certain packet types require polling BUT will not return to you a valid packet because it is processed internally. So even though I did receive a packet and RakNet processed it, I don't get a packet handle back from the polling function. :(

I did update my loop to only Sleep(1) if no packet is received. But again, if there are many of these "hidden" events, I will sleep on them as though no events processed.
If the library only supports polling, then you're out of luck really. I've never used Raknet, but I'd be surprised if it doesn't support blocking sockets at all.

SQL server and the like will use a thread pool and blocking sockets, or IO completion ports to get around this.

This topic is closed to new replies.

Advertisement