Quote:
Originally Posted by Spirited
In addition to that, try to avoid await on server actions like the plague. I'm not saying you're doing this, but servers heavy in asynchronous actions usually perform very poorly. Over concurrency can lead to a whole mess of new problems, some not as easy to manage as others. Also, other server components rely on the map system, and having things like the map system load as an asynchronous action may cause race conditions for loading and accessing map data. I'm not sure if that influences your timing at all, but that may be something you should consider as well.
|
My Raspberry Pi server uses async/await, the TPL and custom threadless tasks using TaskCompletion Source heavily. Here's some stats (running on my PC for Perfmon):
Loading takes 487/48/52 GC calls, picture shows stats after jumping around for 10min killing 4k bidrmen.
[Only registered and activated users can see links. Click Here To Register...]
Tasks provide ContinueWith, WhenAll and other methods that let you easily synchronize the run order and dependencies. They are expensive in terms of allocations - especially threaded tasks, but if you cache task results you can cut down the allocations and GC pressure a ton.
I'm also doing things like updating the screen in a Parallel.ForEach with Aggregation and a single lock per partitioner on the final aggregation step. That again allocates quite a bit of ressources so I'm caching the threadlocal array. All in all, I'm making heavy use of pooling to reduce the GC presure and it works really well.
As you can see on the above screenshot, time spent collecting garbage is merely 0.07% of the entire CPU time spent on the server.
I am still wasting buffer objects on the socket system, somehow I'm not recycling all of them, once that's resolved it should show even less GC calls on Gen0.
The goal of this experiment was to reduce the allocations to a bare minimum using pooling while keeping the memory usage way down without stressing the ARM Quad Core CPU too much. Allocations are especially costly on the Pi, creating a new 850 byte array for example takes 17x longer compared to my PC.
Quote:
|
Agreed. Optimization is fun with stuff like this for a research project and all but it wouldn't be what you'd want for a full scale server. Sooner or later you WILL want tile flagging (even a single byte per coord would be enough. 8 bits should handle all the flags you need as far as co is concerned) and then there's the question of height. Most servers wont need height data but that could change if you are going to implement any custom content or need specific checks.
|
Also since I had two rPi's I tried to make the DMap/Pathfinding run on the other Pi and do some UDP communication between them to offload the load. Never really got far into that but basic access checks were working :)
The DMap System originally had 3 layers. 1 Ground, 1 Mob and 1 for Items. I switched to a single layer to reduce the memory usage while implementing a own BitArray like class based on Int+byte. The byte would allow me to store all flags without the overhead of having 3 bitarray layers. Never got that done though. Was an interesting project while it lasted.
Edit: By the way fang, I'm surprised you answered without insulting me. I appreciate that.
Quote:
|
Newest patch CO client has 267 compressed (.7z) DMap files with a total size of 2.72 MB ...
|
My file isn't compressed just serialized. Should load faster in theory. In my test it loaded all the maps from the serialized file in 480ms.
Quote:
|
dude! I appreciate your work unlike the other's out there! just keep telling and giving advice even telling you the worst thing and this person is even releasing any thread that is useful. unlike your's It kind a awesome!. Keep it up!
|
Thanks :)