Hi, I discovered nim 2 months ago, and it's certainly exciting: the efficiency / readability combination is extremely promising! But... I translated java -> nim a (chess engine) program. Hoping to get a better executable regarding memory consumption and speed.
Up to now, my single-threaded version works correctly and with excellent results. Next step is multi-threading design ... Going through the nim documentation (threads, spawn, locks, threadpools) leaves me in a perplex mood.
Question : Is it possible to multi-thread the engine with the following requirements? :
Data structure
Exploring the nim thread doc ("Each thread has its own (garbage collected) heap and sharing of memory is restricted to global variables."), I am rather discouraged. Would it be some nim way to achieve these goals ?
Tnx for any help, and congratulations for the nim achievements anyway !
Fil
Don't update concurrently the same data structure that will create a huge contention bottleneck due to the heavy synchronization and our program might become slower than single-threaded due to cache thrashing.
Assuming your algorithm is tree-like (I'm familiar with go bot but not chess bot) ideally you have a tree-datastructure and:
If you want to know how big the synchronization cost can be my fibonacci benchmark of GCC implementation of OpenMP versus LLVM shows a factor 100..000x ( https://github.com/mratsim/weave/tree/master/benchmarks/fibonacci ).
Today you can use my experimental weave code that gives you async like semantics and very efficient multithreading, for usage see:
It's experimental code nonetheless it's working and backed by 3 years of PhD research. I suggest you submodule the library.
In the future I hope to make it a proper high-level library, see Project Picasso RFC.
Alternatively you can use Nim threadpools but they suffer from the same issue as GCC OpenMP:
growFunc0(ch:int64) {.gcsafe.} = echo "started " & $nodeMap.len
leads to growFunc0' is not GC-safe as it accesses 'nodeMap' which is a global using GC'ed memory with any compiler option)... it seams that the reasonable action would be to switch back from nim to c++ (and possibly get back to nim when multi-threading evolves)
... unless someone has a working example of similar goals achieved with reasonably readable code.
... it seams that the reasonable action would be to switch back from nim to c++
I think in your initial post you where talking about Java?
Currently multi-threading and parallel processing may be not optimal for Nim, but I think it will improve soon, maybe with newruntime or new GC with better threading support.
But my feeling is, that generally rewriting Java or C++ code to Nim just to improve performance may make not much sense. If you can live with C++ and already have learned it well, or can tolerate high memory consumption and startup time of Java, I see not a very pressing reason to switch to Nim.
Of course this is only my personal view.
I see not a very pressing reason to switch to Nim.
There are many reasons:
Also, OP might just wish to learn Nim. That’s a very good reason to rewrite an existing project, in fact, it might be the best way to learn.
If there is one thing Java is good at it's multithreading with shared references, it's basically the only language with a GC and multithreading support.
However for high performance compute heavy engine, it will be much slower and memory hungry than both Nim and C++ due to pointer indirections/locality of reference issues.
From a performance perspective, a single data structure hammered by multiple threads is a bad idea, whichever language you chose. That is an architecture issue not a programming language issue. Your engine will not scale to 16 cores whether you use C++, java or Nim.