HM3: Testing MultiCore calculation on project to mesh, but getting slow speedup

Hi @stevebaer

I made a script based on your great example on parallel processing:

I am trying to project a bunch of points onto a mesh and wonder if you understand why I only get a 2.3x speed up on a machine with 12 cores/24 threads:

import rhinoscriptsyntax as rs
import random
import System.Threading.Tasks as tasks
import time

def PointsOnMesh(mesh):
    # DENSITY SETTING
    xNr = 200
    bbox = rs.BoundingBox(mesh)
    xMultiplier = rs.Distance(bbox[0],bbox[1])
    yMultiplier = rs.Distance(bbox[0],bbox[3])
    points = []
    for i in range(xNr):
        for ii in range(xNr):
            point=rs.coerce3dpoint( (xMultiplier*random.random(),yMultiplier*random.random(), 0) )
            point += bbox[0]
            points.append(point)
    return points

def ProjectPoints(parallel,points,mesh):
    time1=time.time()
    newPoints=[None]*len(points)
    def calculus(i):
        try:
            projection = rs.ProjectPointToMesh(points[i], mesh, (0,0,-1))
            newPoints[i] = projection[0]
        except:
            pass
    if parallel:
        tasks.Parallel.ForEach(xrange(len(points)), calculus)
    else:
        for i in range(len(points)):
            calculus(i)
    time2=time.time()
    rs.AddPointCloud(newPoints)
    return round(time2-time1,4)

mesh = rs.GetObject("Mesh",rs.filter.mesh)
single = None
multi = None
if mesh:
    points = PointsOnMesh(mesh)
    if points:
        single = ProjectPoints(False,points,mesh)
        if single: print "Single Core:",single
        multi = ProjectPoints(True,points,mesh)
        if multi: print "Multi Core:",multi
        if single and multi:
            print "MultiCore speed up:", round(single/multi,2),"X"

I made it with rs.ProjectPointToMesh() so the mesh isn’t a secured private copy.

Thanks

Edit: You need a mesh in the document, I just used a Heightfieldfromimage and made a 200x200 mesh.

Edit II: Note: On your example I get a 11.5X speedup on a torus. So that seems to work much better.

Hm… I rewrote your example to work on meshes and get the same low speedup.
And then rewrote my example to work on Breps and got a 9X speedup…

So for some reason intersecting meshes with planes or projecting points to meshes are not seeing the same speedgain when ran in parallel.

Parallel processing works much better in C++. In Python you are bottlenecked by the only 1 copy of the interpreter that is running. So unless the function you call takes significant time (because it uses a C++ or C# or C routine independent of the Python interpreter) you will not see a significant speedup and can even see a slowdown.

I get much more parallel speed up by calling routines in a C++ DLL than in sticking to Python only for parallel processing. And this is the when processing meshes.

Regards,
Terry.

1 Like

The first thing I would do to speed this script up in both the serial and parallel modes is to remove the use of rhinoscriptsyntax. That library exists as an easy high level set of functions to call when scripting, but you can eliminate a lot of steps by just directly calling Rhino.Geometry.Instersection.ProjectPointsToMeshes

2 Likes

I’ll give it a try! I also tried with rayshoot.