Wouldn't memory block be a great reason to multi thread?Single-core performance has been optimized to the point where it's almost always waiting for RAM. Adding more threads increases the RAM demand and as I mentioned above: can cause both threads to run slower for having run at the same time due to contention for memory than if they ran in series on a single thread.
Sure, the CPU waits on memory. But while it's waiting for task 1, it could switch to another thread and start a request for more memory. Multi-threading isn't just about increasing multi core performance, but also single core performance for this reason. Lookahead helps (aided by pre-fetching), but by using a single thread you're limiting the program to (assuming an i7 core) part of the l3 cache and only 1 set of l1 and l2 caches. The amount of time waiting for memory should be reduced (when an appropriate amount of work is assigned to a single thread). Memory contention is a difficult problem and requires independent units of work to exist.
Ram demand increase for threading is only an issue if the units of work are small, as the ram overhead of a thread is constant.
However, this is only true if we are simply waiting for memory and there's still capacity in the pipe between memory and the CPU (which I believe there is, as Factorio's performance and my machine learning algorithm's performance seem independent of each other).
Order of work being done does sound like a difficult problem. I wonder where this appears in the game? I thought circuit networks update via pipeline (that is, if there's an operating entity in the middle, it takes 2 updates for the signal to be sent, updated, and then sent again). Is it the logistics network? Are there potentially massive dependency trees involved? many small trees?"Take that, and then still make sure everything is deterministic regardless of thread count without sacrificing the intricate entity interaction and most things simply can't be done in multiple threads: in order to update entity B entity A must first be updated as it can change what entity B will do during its update."
I live in Java/C# land, I hated having to implement multi threading in C++, I don't envy you.
@BlakeMW
I know the topic has been touched on before (especially in some Friday facts), but I hadn't seen any threads on the subject, even with my (albeit weak) search-fu. Could you point me towards some of those threads?This has been discussed to death before...
I think this gets blown out of proportion. Sure, there are things that need to be in place for multithreading to work: thread-safe data structures and definable, independent, units of work. I don't think making the unit structures thread-safe will be hard, the toughest part I'd think is independent work unit identification. This may be what is meant by "ground up" design, but I don't think the cost of refactoring is so high that initial threaded design is requisite. It helps but certainly is not requisite (I personally introduce threading into programs not built with threading in mind on a somewhat regular basis).And the program really has to be designed from the ground up to use this kind of massive-parallelism strategy, with determinism taken into account.
Though, there are just some problems that cannot be parallelized, such as your hole example.
The GPU is used when vector operations can be used, but the different data sizes of entities, and the operation dependant on entity type makes that impractical. While I personally haven't played with GPU operations, that level of multi-threading certainly is a unique beast: not only must the units of work be well defined and independent, but they must have the same operations performed on them. Branching is expensive for GPUs, for instance, so IF, CASE, and tertiary operators are not good.(by the way for this kind of massive parallelism often GPU is used instead of CPU).
TL:DR There are difficult problems to overcome that would take months to get "just right".