犀牛和gh的多线程问题

来源:互联网 发布:python gnureadline 编辑:程序博客网 时间:2024/05/18 00:33

我们来自江河梦小组(Scond Effect Group),工程用到gh,所以必须学习好GH插件,而大部分权威资料都来自国外,所以就组织组员翻译来自GH官方论坛的帖子,以便学习。下面是一篇David的帖子讲解有关 犀牛多线程问题,由林振华同学翻译。

Rhino is already multi-threaded.Some portions of the runtime code use multiple processors*. As time goes bywe'll probably add multi-threading to more and more algorithms, for Rhino5 wetried to at least make all our algorithmsthread-safe, so they can allbe called from multiple threads, this is the first step towardsmulti-threading.

犀牛已经是多线程的。一些在运行时的部分代码使用多个处理器*。随着时间的推移,我们可能会添加多线程到越来越多的算法中去,为Rhino5我们至少试着让所有我们的算法是线程安全的,这样他们就可以从多线程中被调用,这是实现多线程的第一步。

But multi-threading is not justsomething you switch on or off, it's an approach. Let's take the meshing ofBreps for example. Let's assume that at some point one or more breps are addedto thedocument. The wireframes ofthese breps can be drawn immediately, but the shading meshes need to becalculated first. How do we go about doing this? Allow me to enumerate someobvious solutions:

但多线程不仅仅是一些你打开或关闭的,这是一个方法。让我们以网格形的Breps来举个例子。让我们假设在某种程度上一个或多个breps添加到文档。这些breps的线框图可以立即画出来,但需要首先把着色网计算出来。那我们应该怎样做呢?请允许我列举一些显而易见的解决方案:

1.We put everythingon hold and compute all meshes, one at a time. Then, when we're done we'llyieldcontrol back to theRhino window so that key presses and mouse events can once again be processed.This is the simplest of all solutions and also the worst from the users pointof view.      (我们停下所有的事情去完成所有的网格计算,每次一个,然后,当我们完成所有的网格我们就将控制权移回犀牛界面以至于键盘和鼠标事件再次运行。这是所有方案中最简单的一个,但是从用户的角度来看,这是最糟糕的一个。

2.We allow the viewsto be redrawn, mouse events and key presses to be handled, but we perform themeshing in a background thread. I.e. whatever processor cycles are left overfrom regular use are now put towork on computing meshes. Once we're done computing these meshes we can startdrawing the shaded breps. This is a lot better as it doesn't block the UI, butit also means that for a while (potentially a very long time) our breps willnot be shaded in the viewport. This approach is already a lot harder from aprogramming perspective because you now have multiple threads all with accessto the same Breps in memory and you need to make sure that they don't start toperform conflicting operations. Rhino already does this (and has been doing fora long time) on a lot of commands, otherwise you wouldn't be able to abortmeshing/intersections/booleans etc. with an Escape press.

我们允许视图来重绘,鼠标事件和按键被操控,但我们在一个后台线程执行网格划分。即使是正规使用中遗留下来的处理器周期现在都运用于计算网格。一旦我们完成了计算这些网格我们可以开始绘制映射下的breps。这是更好的方法,因为它不阻塞UI,但它也意味着一段时间(可能很长时间)我们的breps不会映射在视窗中。从编程角度来看这种方法需克服更多的困难,因为你现在有多个线程访问相同的所有Breps在内存中,您需要确保他们不开始执行冲突的操作。犀牛已经这样做了,否则你就不能用一个推出的操作来结束网格或布尔计算。

So we can compute the meshes on theUI-thread or on a background thread. How about using our multiple cores tospeed up the process? Again, there are several ways in which this can beachieved:

所以我们可以计算网格在ui线程或在一个后台线程中计算网格。如何使用我们的多核来加速这个过程吗?再次,有几种方法可以实现这个:

1. Say we have a quad-core machine,i.e. four processors at our disposal. We could choose to assign the meshing ofthe first brep to the first processor, the second brep to the second processor,the third brep to the third processor and so on. Once a processor is done withthe meshing of a specific brep, we'll give it the next brep to mesh until we'redone meshing all the breps. This is a good solution when multiple breps need tobe meshed at once, but it doesn't help at all if we only need to compute themesh for a single brep, which is of course a very common case in Rhino.    

假如说我们有一个四核机,即四个处理器由我们处理。我们可以选择指定的衔接第一brep曲面的网格划分和第一处理器,第二brep曲面第二处理器,第三brep曲面第三处理器等等。一旦一个处理器在处理完一个特定的brep曲面网格,我们给它下一个brep划分直到我们完成所有的breps编织完。这是一个好的解决方案当多个breps需要一次性编织,但它不会帮助如果我们只需要计算网格为单一brep,在犀牛中这当然是一个非常常见的情况。

2. To go a level deeper, we need tostart adding multi-threading to the mesher itself. Let's say that the mesher isset up in such a way that it will assign each face of the brep to a new core,then -once all faces have been meshed- it will stitch together the partialmeshes into a single large mesh. Now we've sped up the meshing of breps withmultiple faces, but not individual surfaces.

去更深一层的操作,我们需要开始添加多线程网格化本身。让我们说,网格化是建立在这样一种方式,即它将会分配给每个brep的外曲面新核心,然后——所有的外曲面网格化——它将网状局部网格缝成一个单一的大型网格。现在我们已经用多个面加快了breps的编织,但不是一个个表面进行网格编织。

3. We can of course go deeper still.Perhaps there is some operation that is repeated over and over during themeshing of a single face. We could also choose to multi-thread this operation,thus speeding up the meshing of all surfaces and breps.

我们当然可以更深层面的操作。也许有一些操作,反复在一个单个的曲面的网格编织上。我们也可以选择多线程这个操作,从而加速所有表面和breps的网格编织。

All of the above approaches arepossible, some are very difficult, some are actually not possible if we're notallowed to break the SDK. A further problem is that there's overheadinvolved with multi-threading. Very fewoperations will actually become 4 times faster if you distribute the workacross 4 cores. Often one core will simply take longer than the other 3, oftenthe partial results need to be aggregated which takes additional cycles and/ormemory.What this means is that if you were to apply all of the abovemethods (multi-thread the meshing of individual faces, multi-threadthe meshing of breps with multiple faces and multi-thread the meshing ofmultiple breps) you're probably worse off than you were before.

所有上述方法是可行的,有些是非常困难的,一些实际上是不可能的如果我们不允许打破SDK。更进一步的问题是,多线程方法是有点空泛的。实际上很少的操作会快4倍如果你分发工作在4核。通常一个核心只会需要更长的时间比其他3核,通常部分结果需要聚合需要额外的周期和/或内存这就意味着,如果你要应用上述所有方法,你可能还会不如以前的速度

--

David Rutten

david@mcneel.com

Poprad, Slovakia

* anexample would be the z-sorting of objects inviewport prior torepainting, which is a step performed on every redraw as far as I know.

据我所知一个实例是在视窗重画之前对象的Z排序,这是每一个重绘所必须执行的一个步骤。

原创粉丝点击