CPU utilization?

Started by
6 comments, last by khirsah 24 years, 2 months ago
Hiya, I''m trying to implement a client-server model where the server is run as a separate application (even for a client and server on the same machine). The thing works, but even with a simple (empty) main loop, CPU utilization hits the roof, which is less than ideal for a singleplayer loopback-type game. I''ve noticed that with "dedicated servers" in most games, CPU utilization sits pretty low. This is probably something elementary in Windows programming, but it''s eluded me completely...so what''s involved in affecting CPU usage for a given application? Is this a Win9x-specific thing (ie. would NT''s multitasking have the same results)? Help would be greatly appreciated!!
Advertisement
By empty loop do you mean literally something like:

while (true) {
//no body
}

If so, of course CPU utiliziation is going to go through the roof! It''s going to spend all it''s time executing jmp statements. Once you start throwing in networking calls, it''s going to wait on the calls, dropping your CPU utilization immensly.
Oh okay, but I''m still not clear...does that mean having to make the replies between client and server synchronous? At the moment the loop just progresses if no data is waiting.
So are you just using send()/recv() statements within a while loop? Are you using any form of the select statement?

If you''re using some version of select you shouldn''t get that kind of CPU utilization.
Thanks for your help - I finally discovered Sleep() and it''s running quite nicely now. What I was doing was using send()/recv()''s in a loop, but with ioctlsocket() to set non-blocking mode without understanding what it does (except that it causes recv() to return with an error when no data was waiting). So I guess using select() is the "proper" way to check for data then? What was non-blocking mode actually doing?
When a socket is created, it is by default ''blocking''. This means a call to send() will not return until all the data has been sent. recv() will not return until data is recieved. This means that NO other processing occures in your program. Non-blocking sockets will return immediatly, regardless of how much data is sent or recieved. The return values of these functions are the number of bytes that were processed.

- genovov
To clarify genovov''s post, blocking calls only block the thread they are running in. They won''t necessarily shut down all processing in your program, if you are running multiple threads.

select statements essentially perform signalling when a socket is ready to be read from or written to.

For the standard select statement, you pass it a structure containing the sockets you want to check on, and flags that say what kind of activity you care about. After the call, select will only return once something interesting has happened, and will set flags in structures you direct to it letting you know what kind of interesting things happened. Like there''s data waiting on socket 4, for example.

In winsock, there''s WSAAsyncSelect. This fires a windows message when something interesting happens to a socket you tell it to care about. You specify the window message that''s fired, just make sure it''s not currently used. Someone I know once made the mistake of passing WM_DESTROY to WSAAsyncSelect, so his program would happily shutdown whenever data was waiting for him. The window message parameters tell you what kind of interesting things happened and which socket they happened on.

Also in winsock2 there WSAEventSelect, which is a lot like WSAAsyncSelect, except that instead of firing a windows message, it signals on a Event object. WSAEventSelect is the prefered method of calling select in multithreaded apps.
Aah, that clears it up nicely. The assistance has been very helpful, thanks!

This topic is closed to new replies.

Advertisement