My original code was written for C4D R13 and uses a control thread (C4DThread derived) and a set of 'child' threads (C4DThread derived and based on number of CPUs), using an MPThreadPool. There is no need for locks/semaphores as the child threads are independent of each other.
Okay. C4DThread exists in R20. MPThreadPool appears to be either undocumented or deprecated (?). What's up?
I am in the process of migrating my code and everything else is completed but the threading. Although MPThreadPool is added to C4DThread as a friend class, there is no definition of it. I also see that everything in C4DThread is '/// @markDeprecated'. So, does this mean that I have to convert over to a maxon::ThreadInterface? Is there some migration information on how to achieve this?
you find information on plugin migration in the C++ documentation:
As you see, MPThreadPool was removed in R20. Instead, developers should use the new maxon::ParallelFor for parallelization.
You also find an example in the cinema4dsdk: menutest.cpp
Still a bit (sarcasm) confused. So, there is no longer a need for a 'Control thread' since ParallelFor handles the initialization, parallel running, finalization of the concurrent threads, right?
I also see that there are 2 choices: Dynamic and Static which appear to control the division of labor between the concurrent threads. For static, do I state the division numbers? The criteria in my case is the division of a polygon object by polygons to be processed by the concurrent threads.
Finally, for now, my Control thread initialized, launched, then, once all of the concurrent threads completed, then did assembly of the pieces from each thread into a single new polygon object. This is passed back to GetVirtualObjects() in my ObjectData plugin. Not sure where this assembly would be done exactly for this new paradigm.
ParallelFor::Dynamic() is a utility that manages the creation and execution of jobs (see Jobs Manual) automatically. Typically one should use ParallelFor::Dynamic(); ParallelFor::Static() is only needed for rare, specific cases.
You find an example for "assembly" in the second example on the Parallel Manual page. The "finalize" stage is called synchronously after all jobs have finished to collect and connect all data created. For that, a local data structure based on maxon::ParallelFor::BreakContext is needed.
For this plugin, I am just updating it to work 'natively' in C4D R20 so that users are no longer required to use Insydium's bridge plugin to use the R13 plugin build. There is already a next version (2.0) in the works so I don't care so much about making use of the latest and greatest in this particular situation. Nonetheless, the thing that really annoys me the most is that there is not one example (in the docs, examples, or here) on how to use 'threads' with 'parallelfor'. The simplistic idea of using C4DThreads with ParallelFor, if possible, would probably be enough to achieve my goals. If I must use JobInterface with ParallelFor, then so be it. But my inquiry remains the same: how does this work? Without any examples, I cannot proceed without some trial-and-error guesswork and hope - I have been studying and searching for the past many days to no avail.
It would be great to see an example (even if skeletal) on how to 'pool' threads with ParallelFor using either C4DThread or JobInterface to initialize, launch, and finalize the process.
Thank you very much!
you don't 'use threads' with ParallelFor. ParallelFor is a tool that handles thread (job) creation automatically, the threads are already pooled. You just have to implement the worker code. If you use ParallelFor, you don't have to touch anything else thread related (that's the beauty of it).
There is no thread pooling for C4DThread anymore. You cannot update C4DThread, you should replace it.
If you don't want to use ParallelFor but Jobs instead, you can use Job groups to organizes multiple jobs. See Job Group.
Aha! That helps! I will see how this works this weekend. :)