在Parallel.For
循环中修改值类型数组内容的最佳方法是什么,其中每个任务都可能修改同一索引的数据。
在下面的代码中,sum_normals
数组并不总是包含正确的求和值。
我可以使用锁,但我发现同步运行会更快。创建一个值为并发包的字典,并使用aggregation / sum计算另一个循环中的总和。
var sum_normals = new Vector3[Count];
Parallel.For(0, list.Count, options, i =>
{
var index_1 = ...
var index_2 = ...
var index_3 = ...
Vector3 normal = ...
sum_normals[index_1] += normal;
sum_normals[index_2] += normal;
sum_normals[index_3] += normal;
});
答案 0 :(得分:1)
Parallel.For
has an overload允许在线程开始和线程结束时运行的函数(body
函数的1次以上迭代可以在线程的生命周期内执行)。在这些功能中,您可以创建要写入的本地存储,然后在清理阶段将该本地存储添加到组存储。
var sum_normals = new Vector3[Count];
Parallel.For(0, list.Count, options,
() => //localInit
{
return new Vector3[sum_normals.Length];
},
(i, loopState, localArray) => //body
{
var index_1 = ...
var index_2 = ...
var index_3 = ...
var normal = ...
localArray[index_1] += normal;
localArray[index_2] += normal;
localArray[index_3] += normal;
return localArray;
},
localArray => //localFinally
{
lock(sum_normals)
{
for(int i = 0; i < sum_normals.Length; i++)
{
sum_normals[i] += localArray[i];
}
}
});
请注意,根据...
中的工作量,它可能会更快,只是不要并行执行此操作。