4 ms·
I think the "more cores == faster" benefit is overstated. I've tried to create servers for massively multiplayer games in Clojure and Go. What I've found is th
by stcredzero 10y ago
I think the "more cores == faster" benefit is overstated.
I've tried to create servers for massively multiplayer games in Clojure and Go. What I've found is that it "takes some doing" to be able to efficiently use many processors in parallel. You can't just slap on a pmap call in Clojure or do the equivalent cheesy channel trick in Golang and have good utilization of all your cores in parallel.
It's even more overstated when something like Go can mostly scale as well over multiple cores but be x times faster while doing so.
For what value of "mostly scale as well?" For me, that means doing a little extra design/architecting to break out your Golang server process into multiple worker processes.
it's 10 years later and we haven't seen massively parallel architectures take off.
Because there are still barriers that are a bit too large. You either wind up having to do weird things to do what amounts to efficiently passing data between cores, or you end up using a slower language that's a bit far from the computing mainstream.
- deleted 10y ago[deleted]
- zazibar 10y agoCan you elaborate on how you implemented those servers? Would you still use Clojure or Go for them now? If not, what alternative do you suggest?
- stcredzero 10y agoMy first attempt was a server for a dungeon crawler that superficially looked like a rogue-like, but was actually 12 frames/sec realtime instead of turn based. It started out on Clojure, but I afterwards ported it to Go. In this server, the world was divided into 80x24 subgrids that did most of their processing in parallel. Processing would happen in two stages: 1) local data processing, where each entity got updated in a loop, sending out updates to clients and 2) collision resolution/movement. If I had to do it over again, I would relax the grid's invariant properties, and make each 80x24 subgrid completely independent, which would eliminate the collision resolution step. In my current server, I'm basically sharding my space-game into star systems, with free travel between star systems though "Hyperspace." There is a farm of "worker processes" that is coordinated by a master server. Any instance of a star system can be idempotently spawned when a client is attached to it. < https://www.emergencevector.com https://www.emergencevector.com > I think Go is a good option for writing a game server. You'd have to be pretty profligate to make the GC pause overrun one 16.66 ms tick, and if you miss a tick here and there, who cares?
- Vaelatern 10y agoWhy did you leave Clojure?
- stcredzero 10y agoClojure weenies on IRC. To be fair, the Go weenies aren't much better. If you like hanging out on IRC so that you can emotionally abuse newbies, ask yourself what you're doing with your life.
- Vaelatern 10y agoFascinating, so it was purely a communal decision.
- zazibar 10y agoInteresting. Thanks for the detailed response!
- sbov 10y agoI've always enjoyed writing MUDs (similar to roguelikes), and I found Clojure's killer feature to be immutability, rather than some of the fancier concurrency features like STM. Operations that consume the most resources in a MUD tend to be very amenable to stale, but consistent snapshots, which immutability makes pretty easy to do. My goal was more about responsiveness than throughput though.
- protomikron 10y ago> In this server, the world was divided into 80x24 subgrids that did most of their processing in parallel. Is there any reason why you do update() in parallel? There is certainly some interesting challenges to solve there but did you have a reason to make it parallel other than intellectual curiosity (e.g. better performance)? Afaik a game loop's update() is not the intense part in the game loop (maybe that's different for games with lots of world information update, like roguelikes), but rather render() and IO() are so I am wondering what your design thoughts are.