Reputation: 327
I am trying to iterate through a 2D array and then add to parts of another 2D array in a Parallel.For loop. I have found examples where an accumulation is being done inside the loop on a single variable but am not sure what to do here. GridB is doing accumulation so surely it needs to be locked as items in it could be added to from different threads If it needs to be locked how do you go about locking an entire array like this?
int[,] GridA = new int[D + 2, D + 2];
int[,] GridB = new int[D + 2, D + 2];
Parallel.For(1, D+1 , r =>
{
for (int c = 1; c <= D ; c++)
if (GridA[r, c] != 0)
{
int v = GridA[r, c];
GridB[r - 1, c - 1] += v;
GridB[r - 1, c] += v;
GridB[r - 1, c + 1] += v;
GridB[r, c - 1] += v;
GridB[r, c + 1] += v;
GridB[r + 1, c - 1] += v;
GridB[r + 1, c] += v;
GridB[r + 1, c + 1] += v;
}
});
Upvotes: 3
Views: 490
Reputation: 40838
You could just lock GridB
like so:
Parallel.For(1, D+1 , r =>
{
for (int c = 1; c <= D ; c++)
{
if (GridA[r, c] != 0)
{
int v = GridA[r, c];
lock(GridB)
{
GridB[r - 1, c - 1] += v;
// etc.
}
}
}
});
However, you are serializing all access to GridB
which sort of defeats the purpose of using multiple threads.
If all you want to do is add a fixed value to each element, Interlocked.Add
in the System.Threading
namespace will do the add atomically, so you don't need to take out a lock on the whole array.
Here's a sample of the usage:
Parallel.For(1, D+1 , r =>
{
for (int c = 1; c <= D ; c++)
if (GridA[r, c] != 0)
{
int v = GridA[r, c];
Interlocked.Add(ref GridB[r - 1, c - 1], v);
// rinse, repeat
}
}
Upvotes: 1