在 .net 4.5 中步进并行化 for 循环 [英] Parallelizing a for loop with stepping in .net 4.5
问题描述
我有一个类似于下面代码的函数.它的目的是从一组点中一次取出一个三角形面,其中每三个点是一个面,然后细分它们,用边长不超过 nodeSize 的较小面的列表替换该面.
I have a function that looks something like the code below. Its purpose is to take triangle facets one at a time from an array of points where each three points is one facet, and tessellate them, replacing the facet with a list of smaller facets whose side lengths don't exceed nodeSize.
自然,此功能对于任何逼真的小平面网格来说都是耗时的.我想重构它以使用一些粗略的并行化.但是,Parallel.For 似乎没有办法在保留索引号的同时每隔一段时间遍历数组中的索引.
Naturally, this function is time consuming for any realistic facet mesh. I'd like to refactor it to use some coarse parallelization. However, Parallel.For doesn't appear to have a way to step through indices in an array at intervals while preserving the index number.
记住循环内的 SplitTriangle
函数在计算上不利于并行化,我该如何重构这个函数?
Bearing in mind that the SplitTriangle
function inside the loop is computationally not conducive itself to parallelization, how could I refactor this function?
Protected Shared Function SplitTriangles(Points As IEnumerable(Of Point3D), nodeSize As Single) As List(Of Point3D)
Dim resultList As New List(Of Point3D)
For i As Integer = 0 To Points.Count - 1 Step 3
resultList.AddRange(SplitTriangle(Points(i), Points(i + 1), Points(i + 2), nodeSize * 4))
Next
Return resultList
End Function
推荐答案
您可以使用 Enumerable.Range()
函数为您生成索引.我不太熟悉 VB.NET,所以我打算用 C# 编写它.
You could use the Enumerable.Range()
function to generate the indices for you. I'm not overly familiar with VB.NET, so I'm going to write this in C#.
Enumerable.Range(0, Points.Count / 3).AsParallel().ForAll( loopVar => {
var i = loopVar * 3;
resultList.AddRange(SplitTriangle(Points(i), Points(i + 1), Points(i + 2), nodeSize * 4))
});
<小时>
更新我认为这个版本是线程安全的,但您应该检查以确保它是线程安全的并且结果的顺序正确.
UPDATE I think this version would be thread safe, but you should check to ensure that it is and that the results are in the correct order.
resultList = Enumerable.Range(0, Points.Count / 3).AsParallel().SelectMany( loopVar => {
var i = loopVar * 3;
return SplitTriangle(Points(i), Points(i + 1), Points(i + 2), nodeSize * 4);
});
这篇关于在 .net 4.5 中步进并行化 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!