Reputation: 353
What is the best approach for modifying the content of an array of value types in a Parallel.For
loop, where each task may potentially modify the data for the same index.
In the code below the sum_normals
array will not always contain the correct summation values.
I could use a lock but I found it would be faster to just run synchronously. Create a dictionary with a value a concurrent bag and use aggregation/sum to calculate the sum in another loop.
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;
});
Upvotes: 2
Views: 739
Reputation: 127603
Parallel.For
has an overload that allows for functions that run at thread start and thread end (more than 1 iteration of the body
function may execute over the lifetime of the thread). In these functions, you can create a local storage to write to then add that local storage to the group storage in the cleanup phase.
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];
}
}
});
Note depending on the amount of work being done in the ...
it still might be faster just not to do this in parallel.
Upvotes: 2