• Advertisement
Sign in to follow this  

Reducing CPU usage in Enet thread

This topic is 977 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I posted this question over a year ago but didn't find a good soultion.
 
I use a thread which Enet is created and managed on. The whole thing boils down to 1ms latency vs 100% CPU usage.
 
In the networking thread I can set the timeout to 1ms, such that it will consume less than 1% of the CPU. But this causes 1ms+ latency, or if Sleep() is used inside the Enet library upto 10ms.
 
I want to check for new packets every 0.1ms or less, but not consume more then 10% of the CPU core. How can this be done?

Share this post


Link to post
Share on other sites
Advertisement

When I used to use Enet, I did just as hplus0603 suggested, run & update Enet in the main thread as part of the rest of the frame loop.

 

If I was also rendering, the rendering would naturally limit the framerate & CPU usage, especially if vsync was used.

 

In case of a headless server, the main loop could sleep to avoid spinning at 100% rate, when it doesn't have simulation work to do. Getting the sleep accurate may be a problem depending on the OS.

Share this post


Link to post
Share on other sites

Well, polling on the main thread might work if you manage to guarantee that it is done every 5seconds or less, or else the connection breaks. I don't really want a hiccup on the main thread to cause network issues.

 

Also, as AgentC said, the server side loop spinning makes the server core be at 100% usage unless I put in delays, which I don't want. So either accept 100% core usage or put in Sleep()?

Edited by Tispe

Share this post


Link to post
Share on other sites

Why would the connection break if you call enet_host_service() (or whatever the name was) every frame? Enet uses its own internal throttling to manage the network data flow. Calling the service function should have very little impact on your program if there is no data available on the wire.

Share this post


Link to post
Share on other sites

Yes, 5 sec could be exceeded in situations like loading a new map.

 

Some solutions I can see:

- Divide any long operations into smaller chunks of time, e.g. when loading a map, load new entities into it only until a certain amount of ms has been exceeded, then continue on the next frame

- Increase the ENet timeout

- Keep the ENet thread, and implement sleeping on it instead. However I don't think you will consistently achieve 0.1ms response time and low CPU usage, at least not on Windows, due to less than 1ms "sleeps" having to be implemented with spin-waiting instead, but you can use timeBeginPeriod(1) to get the timer (and thus sleep) granularity down to 1ms.

Share this post


Link to post
Share on other sites

No, if I don't call enet_host_service() for 5 sec it breaks.

Yeah, that is why I suggested you call it every frame. BTW, you can adjust the timeout interval if 5 secs is not what you want.

 

EDIT: Just read AgentC's post. What I do in cases like loading screens is chop up the loading into as small tasks as possible so the network always gets its share of processing, ie. don't do all loading at once but instead lay it out over several frames. In practice this is crucial for MP titles. What I do in my own engine is hand off the Enet host to a background thread whenever it needs to do something that might potentially block the main thread for a long time (several hundred ms), eg. connection and disconnection are done in a background thread. However, all game state sync and simulation is done in the main loop.

Edited by GuyWithBeard

Share this post


Link to post
Share on other sites

Any reason why blocking reads won't work?

You could have one read-thread and one write-thread for the network..

 

Does two threads sharing the same socket/connection work in Enet? Even though one is recieving and the other is sending, is that thread-safe?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement