is Rhino.Geometry.Mesh.Split a threadsave method ? I have one target mesh which i want to split with other invidual meshes. For each split operation i create a duplicate of the target mesh, then do this simple threaded split:
if i run this with 10 jobs, only 6 succeed. If i run it again on the failed 4 ones, 2 work and 2 fail. Splitting individually all works so i asume there must be something wrong.
Mesh.Split in Rhino 7 WIP is thread safe. Please note that there are better and more powerful overloads in Rhino WIP than the ones available on the online help for Rhino 6. Especially, we put a lot of thoughts into tolerance usage. See our new mesh intersection milestones page.
This is probably self-explanatory, but the fact that MeshSplit is thread safe does not mean that you can modify the mesh and at the same time split it, but it means that you can call various splits at the same time if the mesh in unchanged. Please be aware of memory usage piling up, especially if calling this in parallel on large meshes with large splitters.
@dale and @stevebaer , i’ve tried to use the static method as well as the instance method using Rhino 6 (it sometimes fails when threaded but does not fail when individual splits are done with only 1-2 jobs).
@piac, this is for Rhino 6. Of course i do not modify the target mesh while splitting, (i wrote above that i make duplicates of the target for every split job). Each job is done with one individual cutter.
I’ve been trying to make a copy of the Rhino.Geometry.Mesh.Split method using copy.copy or copy.deepcopy but it does not allow to make a class instance from the method itself. It seems that when used like this:
rc = job.TargetMesh.Split(job.CutterMesh)
it is always the same method which is called. (maybe this is what @stevebaer referred to ?).
@dale, here is an example script and scene, the green mesh is the target, the purple ones are the cutters. In the end i am interested in the circular meshes obtained by the split operation. Btw. in this simple example it works, but if the meshes are more complex like the ones i am not allowed to show in public, it fails.
Hi Clement; I asked, and it seems that in Rhino 6 and previous, Mesh.Split is not guaranteed to be thread safe.
There is no difference in calling the method via instance or like a function.
I hope this information helps, at least a little bit.
EDIT: I still reported RH-55950. There is a discussion to maybe add a lock or provide some fixes in an upcoming service release for Rhino 6 code. Rhino 7 code is inherently state-independent.
I am seeing the problem that you are seeing, but there is nothing obvious jumping out at me where the threading issue is located. It does appear to be a threading issue because if I throw a lock on the top level Mesh.Split call everything works. I’ll keep this on my bug list for the time being, but I’m still not sure what can really be done in V6 other than just forcing the entire function to work single threaded via a lock.
I also verified that this does work in V7 as that is completely new code.
that will not make it any faster in V6 i guess (which is why i tried to use threads)
Is Mesh splitting (threaded or not) faster in V7 compared to V6 ?
_
c.
thanks for sending your comments. The focus in the new code is reliability; and there is a lot of work to do already just there.
So, really, the goal now is not to demo how much faster this new code is – a better aim is fixing all bugs of the previous implementation, or at least all the ones that really matter for everyday usage.
While overall performance is very important, there is likely space for optimizations. Again, optimizations are a secondary goal at present. I still took some time to test your model. Here the results. You can test with the same code in today’s WIP.
1. Splitting the mesh with all cutters at the same time, all at once, via command:
V6: 0:00:05.914000
V7 WIP: 0:00:04.312000
Better: V7 took 27% less time.
2. In the script you wrote, I added a simple timer and this line: options.MaxDegreeOfParallelism = 1
With this (negative) change, we can compare the old code and the new one, because at present the old code does not work in parallel.
This is what I get:
V6: 0:00:07.640000
V7 WIP: 0:00:08.214000
Worse: V6 took 7% less time.
3. If we turn on multithreading in your script, we get this: options.MaxDegreeOfParallelism = -1
V6: 0:00:01.691000 (only 5 out of 11 pieces were split), which would put all splits at 0:00:03.7202.
V7: 0:00:02.190000 (all 11/11 split)
Better: V7 took 41% less time than what it seems V6 would have taken to reach the same result, but this is not really an apples-to-apples comparison.
Thank you Giulio for taking the time to make those measurements. Imho these are good news if all splits work and the method is threadable. I am looking forward to V7.
I never said this The new algorithm seems to be giving much better results, though!
There are still two big features to be added that will likely require tweaking and long testing in the WIP – and the first one will be introduced next week: support for cross-intersecting perforations on a single face. This seems to happen a lot in the wild.
The new WIP that will come out this Tuesday, here, takes:
1. 0:00:03.355000 for the command
(down from V7 WIP of last week at 0:00:04.312000)
3. The second parallel loop was also brought down to:
0:00:01.575000
(down from 0:00:02.190000). This makes it faster than the non-completing V6 version.
This is a result of a complementary different logic for some types of faces, not a result of optimizations.