Parallel distribution of a 2D array in C#
I need some advice on parallel workload distribution, based on the heat
distribution problem, using the Jocobi method. The program works by
splitting a 2D array into 4 equally sized grids, via a parallel for - then
to further break down each of the smaller grids into row clusters of e.g.
10 rows which are to be processed in new tasks. The initial grid size is
10000x10000.
The program works but it is significantly slower than my other parallel
implementations, e.g. clustering rows, without splitting the 2D array.
Even when using a for loop, there is a lot of lag. I dont understand why,
due to the access time of the array. For example, calculating: x[5000,
9999] y[5000, 9999] (the bottom, right-hand corner)
Can anyone offer an explanation for the holdup?
class ParallelHeatDistribution_QuadCluster
{
private double[,] heatGrid;
private int gridDimensions;
private int x1, x2, x3;
private int y1, y2, y3;
private int[,] quadDimensions;
public ParallelHeatDistribution_QuadCluster(double[,] heatGrid, int
gridDimensions)
{
this.heatGrid = heatGrid;
this.gridDimensions = gridDimensions;
this.x1 = 1;
this.x2 = this.gridDimensions / 2;
this.y1 = 1;
this.y2 = this.gridDimensions / 2;
this.x3 = this.gridDimensions - 1;
this.y3 = this.gridDimensions - 1;
this.quadDimensions = new int[4, 4] { { x1, x2, y1, y2 }, { x1,
x2, y2, y3 }, { x2, x3, y1, y2 }, { x2, x3, y2, y3 } };
}
/// <summary>
/// Start parallel distribution
/// </summary>
public void parallelDistribution(int clusterRowCount)
{
for (int i = 0; i <1; i++)
{
DistributeWorkload(clusterRowCount, quadDimensions[3, 0],
quadDimensions[3, 1], quadDimensions[3, 2], quadDimensions[3,
3]);
}
Parallel.For(0, 3, i =>
{
//DistributeWorkload(clusterRowCount, quadDimensions[i,
0], quadDimensions[i, 1], quadDimensions[i, 2],
quadDimensions[i, 3]);
});
}
/// <summary>
/// Calculate heat distribution in parallel by assigning work to tasks
based on x-amount of loop iterations. Each iteration represents an
array row partition
/// </summary>
private void DistributeWorkload(int clusterRowCount, int xStartPoint,
int xEndpoint, int yStartPoint, int yEndpoint)
{
/* calculate data partition cluster for parallel distribution. */
int clusterCount = (gridDimensions) / clusterRowCount;
/* Parallel task arrays for black and white elements */
Task[] taskArray1 = new Task[clusterCount];
Task[] taskArray2 = new Task[clusterCount];
try
{
/* assign work to for set of tasks calculating the "black
squares" */
int c = 0;
for (int x1 = 0; x1 < clusterCount; x1++)
{
int clusterSize = c;
taskArray1[x1] = new Task(() => setTask(clusterRowCount,
clusterSize, true, xStartPoint, xEndpoint, yStartPoint,
yEndpoint));
c = c + clusterRowCount;
}
/* assign work to second set of tasks calculating the "white
squares" */
c = 0;
for (int x2 = 0; x2 < clusterCount; x2++)
{
int clusterSize = c;
taskArray2[x2] = new Task(() => setTask(clusterRowCount,
clusterSize, false, xStartPoint, xEndpoint, yStartPoint,
yEndpoint));
c = c + clusterRowCount;
}
/* start all tasks */
foreach (Task t in taskArray1) t.Start();
Task.WaitAll(taskArray1);
foreach (Task t in taskArray2) t.Start();
/* and wait... */
Task.WaitAll(taskArray2);
} catch (AggregateException e){
Console.Write(e);
}
}
/// <summary>
/// Task: calculate a cluster of rows
/// </summary>
/// <param name="y"> y-axis position </param>
/// <param name="isFirst"> determine grid element set </param>
public void setTask(int clusterRowCount, int currentClusterCount, bool
isFirst, int xStartPoint, int xEndpoint, int yStartPoint, int
yEndpoint)
{
int yPos = yStartPoint + currentClusterCount;
double temperature;
for (int y = yPos; y < yEndpoint; y++)
{
for (int x = xStartPoint; x < xEndpoint; x++)
{
if (isFirst && y % 2 == 0 || !isFirst && y % 2 != 0)
{
if (x % 2 == 0)
{
temperature = (heatGrid[y - 1, x] + heatGrid[y +
1, x] + heatGrid[y, x - 1] + heatGrid[y, x + 1]) /
4;
heatGrid[x, y] = temperature;
}
}
else
{
if (x % 2 != 0)
{
temperature = (heatGrid[y - 1, x] + heatGrid[y +
1, x] + heatGrid[y, x - 1] + heatGrid[y, x + 1]) /
4;
heatGrid[x, y] = temperature;
}
}
}
}
}
No comments:
Post a Comment