multithreading is exactly as hard as everyone, including me, has always said it was. this is hell
Can you elaborate
I am curious
He means writing a computer program that uses multiple cores at the same time. synchronizing them is a nightmare. It's like herding cats, except they're 11-dimensional cats and you only exist in 3-dimensions.
The real trick to doing multithreading right is to realize you're doing it wrong before you start then design a system that doesn't need to be synchronized in the first place. If you're doing locks and mutexes and shit everywhere, then you already did it wrong. The right way is that any thread can do read-only on data it needs, but they've each got a separate data area they write to. Like, if you want to split up the game to update physics for a lot of objects, make each thread responsible for X amount of objects. they can read the data for other objects for collisions etc, but they can only write the data for their allocated objects (and make sure these are packed into actually separate memory blocks for the best effect). If you have a thing where two threads can/will both update the same object, so they have to uses locks and waiting to make sure nothing fucks up, you didn't think it through enough. "I'll need a lock/mutex here" is the first thing they teach you about multi-threading, but it should be the absolute last resort in your actual design.
One of the big stumbling blocks is in fact what's considered good design in the first place: object oriented design. What's a perfectly good and clean design for a single-threaded app turns into a quagmire when you have multiple threads of control running at once.
not he, also,
I'm doing this for Space Station 13, you see. I'm using extools, a rather recent invention, basically DFHack for Byond. Here's the crux of the issue: I
cannot run any byond functions in another thread, and at least
some data must be available to the main thread.
The main way I've solved this is by, indeed, minimizing shared state as much as possible. Shared state is the enemy, yeah, and I do try to go with the single-writer-many-reader paradigm here, which is the usual trick for things.
Anyway, it works. I've taken the bogeyman, the cause of so much stress over the years, the laggy-ass monster that the game is built on, and took it from something that takes 0.35 seconds under load to something that takes 0.02 seconds under load, even though it actually does over 5x as much actual processing.
But that's a stretch of "works". It crashes. I don't know when, nor why. But it sure does. It could be a segmentation fault; it could be an out of memory error; I don't know, because it
takes a goddamn hour. This is horrible.
And yeah, I've gone from "one mutex per gas mixture" to "one mutex per queue" to "one mutex, period". I straight-up
can't improve on that, though; I have no choice but to have shared state. Both the main thread and the atmos thread
have to write to the same data, sometimes, and the atmos thread simply cannot do certain things with the data given to it.