V6 Feature: Multi-threaded GH Components

The latest WIP includes a new behavior in Grasshopper that we are experimenting with to improve performance; multithreaded component solving.

The following four components have been modified to perform calculations using multiple threads.

  • Contour
  • Dash Pattern
  • Divide Curve
  • Boundary Surface

We are decorating these components with small dots in the upper left corner to help you understand the component’s capabilities and current ‘mode’ of operation.

No dots : the component does not currently support multi-threaded calculations
One dot: the component does support multi-threaded calculations, but is currently calculating with a single thread (i.e. legacy mode)
Two dots: the component does support multi-threaded calculations and is using the feature

For components that do support multi-threaded calculations, the feature can be enabled/disabled using the right click context menu on the component itself.

What to test:

I am not interested in timing results at the moment. What I want to make certain is that the output from these components produce the exact same results and same data structure (for trees) when run in both single threaded and multi-threaded modes. Of course, I’m also interested to know if any other unusual behavior appears by using these components.

These initial four components are our prototypes to ensure things are running correctly before converting other components over to be able to using multiple threads.

16 Likes

“Assign all available processors to this component”

What about (default=All, 1..n) ? :slight_smile:

Edit:
And, the number of dots, see the options above… (or the actual number of threads)

// Rolf

We are trying to keep this as simple as possible for now and depend on the .NET framework’s default TaskScheduler. Imposing maximum concurrency limits is something that we can investigate once we are comfortable with the current system in place.

Point well taken.

// Rolf

It seems Boundary Surface is not using more of the CPU when multi threaded. I am inputting 500 curves, with and without multi threading the CPU usage is at around 12% as per Task Manager->Performance.

Are the output results the same?

The only way I’ve been able to really test CPU usage is to hook a component up to a slider and scrub it back and forth to ensure a solution is always computing. Maybe you will see different results with Task Manager in that case

Do the other components appear to use multiple CPUs?

Boundary Surface
I did the test again with 16000 curves, the solution takes more than 15 minutes to compute. During this time CPU usage is at a constant 12.5%, with and without multi threading. The output seems identical (as far as I could check for this amount of curves). Scrubbing a slider with less curves made no difference in CPU usage, but it might be misleading because I hardly get CPU usage above 10% with the slider.

Contour
With 30 Breps and a contour distance resulting in around 4300 contours, I get CPU usage up to 80%. Seems to work fine. Computation takes around 10 sec.
With 350 Breps and a more sparse contour distance, again resulting in around 4000 contours, I get CPU usage only to 15%. Computation takes around 20 sec.

So I guess I misunderstood the multi threading approach. It seems that calculations are only multi threaded on a per item basis, not at the tree level.

Do you have a sample you can share? This is the first week this feature has even be implemented and there is a good chance I missed some cases which should be multithreaded.

A sample would really help. I don’t know how to repeat the tests that you’ve done

Please see the following Rhino and GH files.

Untitled.3dm (822.4 KB)
unnamed.gh (49.0 KB)

Hi all,

For anyone searching for the contour is the one that cuts brep or meshes. It is sitting in Intersect>Mathematical.

I will give them a try. Thanks for the effort, I was talking with some colleges the other day in the office about Rhino performance and investment in equipment and these steps put some hope in the mid-term future.

Cheers.

Perfect; thanks!

I’ve only looked at the boundary surface component so far and know what is going on. Boundary surface is set up to take a big pile of curves all at once and generate a bunch of surfaces. That task in itself is single threaded. If you hover over that component, you’ll notice that it only ran once since it is dealing with the big list of curves all at once.

Now in your case, you have a bunch of disjoint curves and expect to get a bunch of separate surfaces. If you look at the attached gh file, I added a graft component in between the curves and the boundary component to force the boundary component to solve 800+ times (once for each curve) instead of once. This is where multiple CPUs will be utilized and you will see performance differences.
multisolve_boundary.gh (44.6 KB)

I’ll start looking at the other examples and get back to you. Thanks

Yes, thanks for the clarification and please do try this feature out.

We’ll probably just keep converting components over to this new system over time once we see resolve any problems that may be found in the prototypes. I’m also open to requests for which components to focus on.

Once we have the feature locked down, I plan to create a document to show component developers how they could convert their components to be “task capable”.

1 Like

@stevebaer that will be an absolute piece of cake :slight_smile: Only with the glance that you gave I started searching in microsoft documentation, curious about how to implement it. Any documentation will help a lot in the process. Thanks in advance.

Hmm… for the contour samples that you posted I can see my CPU utilization hit 90+% in task manager and results are produced in about half the time. I’m not exactly sure what is happening in your case.

This is my work-in-progress document that I’m putting together. This will get transferred to our developer documentation site once we have a decent process in place.

I’m sure you can tell that this document is just a rough draft :slight_smile:

1 Like

Thanks! I will have a look at it straight away.

BTW, testing on my workstation, @silvano results are similar to mine. The only difference is that for the two low performance cases, my CPU is always around 20% (not 12%).

My CPU is a Intel Xeon…I didn’t read in deep but I don’t know if CPU architecture could influence in how multi-threading should be implemented.

Cheers.

PS: Looking at the definition closely, I could find something interesting:

  • If you deactivate the second case in @silvano definition and activate it again with the multithread option activated, the component is calculated using up to 20% of the CPU.
  • If the component is not deactivated, and you just switch between multi or single threaded, the CPU usage for the multi-threaded option is 80% or more being the single threaded option similar to the multi-threaded staring from the deactivated component.

I hope that this helps.

As long as the results are the same and the times are at least the same in not faster than I’m happy. I’ll keep playing around to see if I can repeat this case.