Split list for multi-threading?

This question may be totally moronic so pardon me if that’s the case.
How does multi-threading work? If I split a list and distribute the sub lists to copies of a single-threaded component will grasshopper magically make it multithreaded?

There is no such thing as magic. So I think no is the answer. From what I can tell, in general GH is a single-thread application, but recently some (a few) of it’s functions have been recoded to be multi-threaded. These functions have 2 small dots at their top edge. Aside from these special cases GH seems to calculate each function in order by itself, and uses only 1 CPU when doing this. Writing multi-threaded code is difficult and my guess is that more of it may (or may not) appear in GH2.

The way multi-threaded applications work is like this: first, the software looks at the data is has to process. If it sees that hunks of the data can be processed independently of all the other parts it splits these hunks into separate pieces and assigns a separate CPU to process each piece. This allows multiple CPUs to process multiple hunks of data simultaneously, which greatly reduces elapsed time. When each CPU is finished processing the program takes the resulting processed data from each CPU and assembles it into the proper place to produce the final result.

A good example of this is brightening a JPG image. Brightening means increasing the value of the Red, Green, and Blue pixels throughout the image. To do this a program like Photoshop splits the image into a number of small pieces, and lets each CPU process the pieces assigned to it. Then, when all the pixels have been processed, it reassembled the image pieces into the complete and brightened image.

In general GH can’t do that because (most of the time) GH is sequential in nature. That’s what the wires are for, right? So figuring out how to multi-process a GH script is probably something only a brain can do - not a program. But then maybe a better brain than mine can do this.


Given the opportunity (and rather totally irrelevant if you are not in the coding business) here’s a classic - by the best - on that matter:


BTW: // is not a big red button - press and be a happy bunny.


thanks for sharing this very interesting article!

Wow - that is a great article Peter - thanks for the reference. I’ve never been able to deal with the syntax used by the various flavors of C (all those braces, brackets, semicolons etc. just freak me out), but I do appreciate the capability the Thread statement allows. Who knows - maybe I’ll give it a try one of these days. Or maybe this: The APL Programming Language Source Code - CHM

Well … all that are like Godzilla: the more the better:

1 Like

:see_no_evil: :hear_no_evil: :speak_no_evil:

To add a couple of things here:

Many components would never work under parallel execution. One of the most important criteria of parallel compution is having atomic pieces of logic!

E.g. If you want to trim 1 curved-surface with 1000 closed-curves, then you cannot parallize this!
Why? Because the logic of cutting a surface with one closed-curve results in a new trim boundary. The result of the trim, has then be used by the next trimming operation. In other words, the result of one operation affects the other, thus its not atomic.
(On a lower level you can increase speed by only creating the render-mesh once, but thats another topic…).

However if you trim 8 curved-surfaces with 1000 closed-curves, where 125 curves corresponds to one single surface, then this operation could be placed on 8 threads. But thats the ideal world…

Another point is threadsafe data-access…
Usually you can read from multiple threads, but you can’t write from multiple threads at the same time.
Multiple data is usually stored in data-collections. If you not choose a thread-safe collection, then you might access data at the same time, leading to a crash. Now, this may occur or may not. Which is a really nasty behaviour to debug. Usually the problem is best solved by putting your data in thread-dependent places. However all the shifting of data is a performance bottleneck. This is why, parallel computation is not always faster! It also depends on what and how often you do that!

1 Like

Not sure what you’re suggesting. I need to analyse the exposure of a 50k face mesh to massive group of vectors. The bigger the better. This is basic ray-tracing, so a common multithreaded application.
If the “exposure” grasshopper component was multithreaded it would be perfect, but it’s not, so there’s a limited number of samples.
Splitting the data in lists works if I output the data and run it on other instances of rhino. I then collect all the processed data and merge it.
Surely there’s a better way but that’s the best I can do at the moment.

Well my answer was more a general one. My point was basically just that multithreading is not the holy grail of improving performance. This is because it demands certain conditions top be true and because its (more) difficult to code. In order to process data “thread-safe” (not causing a crash) you have do a couple of extra steps. Creating a new thread, moving data in a thread-safe collection or in multiple collections, synchronising, moving back into a single collection…, this all comes with an overhead. This explains why it may not necessarily improve performance, nor that you can’t just implement any component as multithreaded.

Usually raytracing is solved on a gpu, not on the cpu. This is because a gpu is optimized for these kinds of calculations. But since you are probally bound to GH, I think in this case writing as simple Parallel.For loop will solve it for you. The Parallel library will take care about the steps mentioned above for you, but this is a special case and not suited for many parallelization tasks.

But generally speaking, the idea of visually defining multithreading over Grasshopper, sounds totally logical for non-programmes, but does not fully address the complexity of this subject. Not the first time I’ve heard that.

1 Like