🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Async vs. Nonblocking

Started by
14 comments, last by fprefect 23 years, 4 months ago
Why would seperating read/writes be stupid? If your using blocking sockets, read/write operations block the thread, thus if you sequentially read/write in the same thread they become linked, performance wise. Hit a spot of heavy action, more data is sent, which then slows down the read operation, which effectivly reduces the number of updates per second for player input, which then trickles through the system, making it appear unresponsive and laggy on the client side. It all ties together. Well for an action game, you want to reduce any overhead latency, and this is a major one. For a MMORPG, maximizing server performance would likely overide that issue, and so using 1 thread / socket might be acceptable.

The other major transactional latency I''ve noticed is getting the packets from the sockets thread to the master thread, and processing it in step with the worlds updates. Unless your world logic can work on a sub-tick level, the packets more likely than not will be processed on the next tick, so that adds about 1/2 tick worth of transactional latency from that as well. (Most packets dont arrive at exactly the end or beginging of a tick on average i''ve noticed).

It all starts adding up, latency really is a game killer. The less transactional latency, the better your games performance.

Im thinking about switching to winsocks asynchonrous sockets myself, or write a test program to test out it''s transactional latency overhead.

Good Luck

-ddn
Advertisement
ARGHH.. hit the wrong button, I have to write everything again

Why for heaven''s sake would you seperate reads from writes? First of all, almost all communication works like this: You read from the pipe/socket, then react to it (i.e. write). If you split this into two threads, almost all of the time only one of them will be active, while the other one waits on its counterpart. This is simply a waste of system resources. Secondly, you''d have to share a socket across multiple threads, and while this is possible, I think it''s really not a good programming technique and might cause trouble with the OS (internal fs code locks etc...).

You also seem to forget some things about multithreading. Multithreading, especially when the threads interact a lot, is very expensive. First of all, you have to be _very_ careful to avoid races, especially deadlocks and lock violations which result in invalid data. Then, threads take up resources just like sockets do, and there''s an upperlimit of threads on all OSs. Also, all the semaphores and stuff you will have to use to ensure safe process locking require many calls into the OS kernel (and kernel calls are slow) and take away system resources. On top of that, switching to a different process/thread is nothing to be done lightly. Context switches can be very time consuming (this depends on the underlying hardware though). All in all, there is really _no_ reason whatsoever to use threads in a server, unless you have access to a multiprocessor server in which case you might consider one thread per processor. And even then, this might not pay off unless you''re very careful, because of all the buslocks and cache problems you get when several processors access the same part of system memory (which will definitely happen in a game server).

Maybe, if you want to write an MMORPG, you might consider different threads (I''d say one thread per processor; no point in doing this on a single processor machine), but design it so that each thread has a different area of responsibility on the game''s world map. Then (almost) all your inter-process locking/data locking troubles will disappear, and threads are indeed efficient. You''d have to write code to hand players from thread to thread when they travel to different parts of the map etc., but in this case, and only in this case, would a game server with multiple threads be effective.

I hope this was enough to convince you

cu,
Prefect

---
Sanity is the trademark of a weak mind.
Widelands - laid back, free software strategy
Ok, waiting for a frame to be rendered, even in 2D, is *WAY* too long to wait. I was hoping to get my response times below 100us, I can''t sit & beat pud for 40,000us while a 3D scene is rendered.

Though you can change the default stack size (and it''s not committed), a thread by default sucks up 1meg for stack space. If not for VM, you couldn''t possibly have a thread per connection, with VM it slows the piss out of the machine.

Using 200 threads to handle network tranmissions is exactly how you''re not suppose to use threads.

...
While most data transmissions work in a syncronous manor, RT data transmissions do not - xsp not a networked game! You''re going to be getting bombarded my position updates, and you don''t ask for the client to send them, it just does, you may build in some flow control to dynamicly raise or lower the rate - but you don''t knock each time you want data.

...
Why wouldn''t you want two threads, one for reads & one for writes?
Well most networks can send & receive concurrently now a days, but there''s still only one bus between you and the NIC, so it cannot increase performance. If it''s not increasing the performance there''s no reason to blow system resources on it.

- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Game data transmissions are still "kind of" synchronous. The client sends position changes. The server will have to verify that (unless you like cheaters) and thus send an ACK back. It will also send some information about entities that will enter the line of sight of a player. Agreed, it''s not completely synchronous, but even if you don''t think it is, you still have to see that the data overlap between read and write operations is extremely big, so using two threads wouldn''t be effective at all.

And threads _never_ increase performance, they will only make your game slower (more system resources used up, context switches take time, synchronizing waits, etc...) - they might decrease response time in some cases though. The only exception where threads will increase performance is on multiprocessor machines, but only up to one thread per processor, and only when there''s no other program running on the machine.

cu,
Prefect

---
Sanity is the trademark of a weak mind.
Widelands - laid back, free software strategy
Well, after researching it some, i still come to the conclusion that seperating blocking sockets read/writes into indiviudal threads is still nessecary for my game (an action game). They greatly simplfy the flow of control and overall design. However the message pump + OS socket management seems to me even simpler and more robust than using blocking sockets + threads design, however it would lock me into the winsock api.

Here is a good winsock refrence where i did most of my research :

http://www.cyberport.com:443/~tangent/programming/winsock/

Well Good Luck

-ddn

I wish I still had it in front of me, but while I was perusing the MSDN docs earlier today, I came across a blurb about blocking with ReadFile & WriteFile - If a Read is in progress, the write will block & vice-versa. So inorder to do concurrent read & write you must use async...

And a thread will increase network performance (at the expense of graphic performance) if it swaps out a render into your socket thread(s) when an event signals.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement