Has somebody successfully implemented that with an actual performance increase?
I've played around with that over Easter, the code works, I can see all 20 Cores being utilized, but the code runs 50-100% slower than single threaded.
Supposedly that is an issue with Python/Ironpython and "from threading import Thread". In Python you should use "from multiprocessing import Process" instead. But that one doesnt' work in IronPython, doesn't seem to be implemented correctly in 2.7 or 3.4 and throws an error about missing modules.
For starters I tried to pimp my perpendicular to DTM macro. Since you always need to test all triangles for a viable solution, where the normal from the point in question lies inside the triangle, it would massively benefit from multiprocessing. Have each core do the computation for a certain range of the triangles and at the end just output the shortest distance.
from threading import Thread, Lock
from multiprocessing import cpu_count, Process
# use multithreading to check all triangles for a solution
threadcount = cpu_count()
listlock = Lock()
# limit threadcount if there are more than work to do, otherwise we'd end up with double-ups in the result list
if threadcount > verticelist.Count / 3:
threadcount = int(verticelist.Count / 3)
#threadcount = 1 # debug manual thread limiter
self.error.Content += '\n' + str(verticelist.Count / 3) + ' Triangles - ' + str(threadcount) + ' Threads used'
self.exc_info = None
threads = [Thread(target = self.perpdisttotriangle, args = (listlock, computeplumb, vertice1_sel, verticelist, dtmresults, threadcount, threadindex,)) for threadindex in range(threadcount)]
# start threads
for thread in threads:
thread.start()
# wait for all threads to terminate
for thread in threads:
thread.join()
if self.exc_info:
exc_type, exc_obj, exc_tb = self.exc_info
self.error.Content += '\nan Error occurred - Result probably incomplete\n' + str(exc_type) + '\n' + str(exc_obj) + '\nLine ' + str(exc_tb.tb_lineno)
def perpdisttotriangle(self, listlock, computeplumb, vertice1_sel, verticelist, dtmresults, threadcount, threadindex):
try:
trianglesperthread = math.ceil(verticelist.Count / 3.0 / threadcount) # must be 3.0 otherwise it won't be a float and is rounded down before I can round it up
istart = int(0 + threadindex * trianglesperthread * 3)
iend = int(0 + threadindex * trianglesperthread * 3 + trianglesperthread * 3)
if iend > verticelist.Count:
iend = verticelist.Count
for i in range(istart, iend, 3):
............................
------------------------------
Ronny Schneider
------------------------------