我正在使用TPL库来并行化2D网格操作。我从实际代码中提取了一个简单的示例来说明我在做什么。我得到了想要的结果,并且我的笔记本计算机(12)上的处理器数量加快了计算时间。
我很乐意就我的属性如何声明获得一些建议或意见。同样,它可以按预期工作,但是想知道设计是否会更好。先感谢您。
我的简化代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Gridding
{
public abstract class Base
{
/// <summary>
/// Values representing the mesh values where each node in the gridis assigned som value.
/// </summary>
public float[,] Values { get; set; }
public abstract void Compute();
}
public class Derived : Base
{
/// <summary>
/// Make the mesh readonly. Is this necessary?
/// </summary>
readonly Mesh MyMesh;
Derived(Mesh mesh)
{
MyMesh = mesh;
}
public override void Compute()
{
Values = new float[MyMesh.NX, MyMesh.NY];
double[] xn = MyMesh.GetXNodes();
double[] yn = MyMesh.GetYNodes();
/// Paralellize the threads along the columns of the grid using the Task Paralllel Library (TPL).
Parallel.For(0, MyMesh.NX, i =>
{
Run(i, xn, yn);
});
}
private void Run(int i, double[] xn, double[] yn)
{
/// Some long operation that parallelizes along the columns of a mesh/grid
double x = xn[i];
for (int j = 0; j < MyMesh.NY; j++)
{
/// Again, longer operation here
double y = yn[j];
double someValue = Math.Sqrt(x * y);
Values[i, j] = (float)someValue;
}
}
static void Main(string[] args)
{
int nx = 100;
int ny = 120;
double x0 = 0.0;
double y0 = 0.0;
double width = 100;
double height = 120;
Mesh mesh = new Mesh(nx, ny, x0, y0, width, height);
Base tplTest = new Derived(mesh);
tplTest.Compute();
float[,] values = tplTest.Values;
Console.Read();
}
/// <summary>
/// A simple North-South oriented grid.
/// </summary>
class Mesh
{
public int NX { get; } = 100;
public int NY { get; set; } = 150;
public double XOrigin { get; set; } = 0.0;
public double YOrigin { get; set; } = 0.0;
public double Width { get; set; } = 100.0;
public double Height { get; set; } = 150.0;
public double DX { get; }
public double DY { get; }
public Mesh(int nx, int ny, double xOrigin, double yOrigin, double width, double height)
{
NX = nx;
NY = ny;
XOrigin = xOrigin;
YOrigin = yOrigin;
Width = width;
Height = height;
DX = Width / (NX - 1);
DY = Height / (NY - 1);
}
public double[] GetYNodes()
{
double[] yNodeLocs = new double[NY];
for (int i = 0; i < NY; i++)
{
yNodeLocs[i] = YOrigin + i * DY;
}
return yNodeLocs;
}
public double[] GetXNodes()
{
double[] xNodeLocs = new double[NX];
for (int i = 0; i < NX; i++)
{
xNodeLocs[i] = XOrigin + i * DX;
}
return xNodeLocs;
}
}
}
}
仅使用100到150个数组元素,并行设置开销会抵消增益。当修改XOrigin,NX,YOrigin或NY时,可以缓存GetXNodes()
和GetYNodes()
的结果并使所缓存的值无效。