Please explain how does server works if all Unity runs in one thread?
At a high number of connections in case of using one thread requests will be delayed by processor?
network part is multi-threaded to reduce time to handle sending messages when you have a lot of connections.
Script Callbacks for network events all happen in the Unity main thread.
So Unity networking is single threaded? Then how can it handle 100+ connections?
I join to a question. How to create high perfomance server to handle several thousands of connections? Or it impossible and UNET designed to only work with Multiplayer Service without server logic?
Unity Networking is being rolled out in phases, this is the first phase which handles common game requirements. I would imagine it’s ideal for peer to peer games where you’re having 2-32 players. Future milestones (check blog) will add more functionality, scaling all the way up to MMO someday.
unet library contains two different part; first part is working in main unity thread. the second part working other thread(s). When you send message you actually put message in the send queue which will utilized by network thread(s). When you check is message received, you actually check the received queue. Both operation is o(1) complexity for user.
For client library this network thread which utilized all network work is one. For server library it will be pool.
So then what is about thread safety? DO I need to lock concurrent collections on server?
Sorry do not understand you question. UNET expects that there is only one user thread, so function Send() and PopData() are not thread safe. If you use more than one thread - you should create your lock policy I guess
I mean, if a peer connects to the server does server create a new thread for each peer? If not than it means that in 500+ peers connected and sending 20+ requests each it would be laggy… Such servers as photon and smartfox, use one thread for each peer.
PS photon use phibers for each peer, but but whats about UNET
No. In 5.1 in UNet there is one network thread, then script callbacks happen in the Unity main thread. This may change in future versions.
Is there any formula to count how many connections + number of requests it is comfortable for 1 thread?
I mean, if a peer connects to the server does server create a new thread for each peer? If not than it means that in 500+ peers connected and sending 20+ requests each it would be laggy… Such servers as photon and smartfox, use one thread for each peer.
Gothca, Sean has been already answered.
Performance: Difficult to say, but I have some digits in my pocket. I did stresses following configuration:
I created echo server just as unity game (but without gui and any rendering/physics stuff inside)
0. Size of the packet whole packet ~ 50bytes, all messages are reliable
- Echo server working on one machine, and multiply echo clients working on another, connection WiFi 11g
2.Echo Server on Win, Android (Samsung S4) iPad 3rd generation.
For Server on win combination it was ~2000 pkt per sec ~800kBit (it is ~15% of full allowable bandwidth) per sec and server fps rate was stable 60fps… so I can conclude that maximum value should be significantly greater.
For Server on android it was ~1600 pkt per sec.
Take into account
- that for computer itself there is not significant difference to handling 50 or 500 bytes packets (all computation are the same + two memcpy call per packet)
-it was a goal to compare client library performance on mobile devices vs pc standalone client
-all above mentioned digits described full stack - user create message call send, library delivers message to other peer, echo server receives this message an replay them back…
it is what I have for this library
The problem is that you test it sending packets from 1 client. If you try 100 clients and 1 thread you’ll notice that some clients experience a heavy delay cause one thread is waiting for whole 2000 packets to be processed
The problem is that you test it sending packets from 1 client. If you try 100 clients and 1 thread you’ll notice that some clients experience a heavy delay cause one thread is waiting for whole 2000 packets to be processed
With fps = 60 and one message per frame it is impossible to reach 2000 packet per sec… For sure it was about 50 clients…
No, SmartFoxServer does not run one thread-per-peer.
Typically you can run tens of 1000s of users with a 30-40 threads max. Btw, that’s the only way in which a server can scale in the tens or hundreds of thousands.
I know it, because I wrote the server’s engine
cheers
Lapo
Running a stress test on WiFi is not a good idea, the network will generate a lovely bottleneck.
Running a stress test on WiFi is not a good idea, the network will generate a lovely bottleneck.
I know The main task of my stress testing was to compare performance between mobile devices and PC. UNET so far is client library. However, as the above-mentioned digits can give an idea about performance in general, I presented them
Typically you can run tens of 1000s of users with a 30-40 threads max.
Hm it depends… How many cores do you have, how many io operation are you going to perform, are you io operation can be done async or not? …
I was referring to non-blocking I/O, of course. Blocking I/O is too hard to scale.
Blocking io, one thread per connection scales better then people think. Most of what you hear is from years ago, and people just keep repeating it until it’s something ‘everyone’ knows.
10-15 years ago non blocking started to get popular primarily because linux threads sucked so bad. But those days are gone. So basically where threads and context switching used to be much more expensive, now the non blocking selectors are what is expensive (comparatively). Idle threads use basically 0 cpu, and not only is context switching just not a big factor, the difference in context switching between a handful and thousands of threads is minimal. Connection per thread also lets you use blocking data structures which are faster.
My own tests using Netty (popular java NIO framework) vs connection per thread weren’t even close. NIO used more cpu, created more garbage, and was slower all the way around. Some of that was Netty not NIO, but it was mostly NIO itself. It’s pretty obvious what’s using what when you spin up visualvm and poke around.