我的代码确实存在问题,这个问题非常慢,无法使用。我必须在下周提供我的结果,通过此代码需要超过4周! 由于此代码计算流体运动,我们处理超过100万个单元格。因此,我的主要 For循环(顺序很重要)计算量很大,现在每个输出需要12分钟。 想象一下,我需要至少5000输出!
任何人都可以帮助我提高计算速度吗? 要么 你能帮我理解如何将For循环更改为PLINQ语法吗?
我很沮丧
//implementation of time nt = 1,000,000
For (int t=0; t<nt; t++)
{
// main calculations, 2 dimensional
for (int i = 0; i < nx; i++)
{
for (int j = 0; j < ny; j++)
{
if (!Cells[i, j, 0].IsVirtual)
{
// calculate x velocity - nx = 1,000,000 & ny = 1,000,000
// calculate y velocity
// Data for each (i,j) affect (i+1,j+1)
}
}
}
}
答案 0 :(得分:1)
为了能够使用PLINQ,您需要将二维for循环更改为可以处理的元素序列(例如IEnumerable<T>
)。您可以使用以下代码将x和y值创建为序列:
var indices = Enumerable.Range(0, nx).SelectMany(
_ => Enumerable.Range(0, ny),
(x, y) => new { X = x, Y = y }
);
然后,您可以使用Where
:
indices.Where(index => !Cells[index.X, index.Y, 0].IsVirtual)
然后,您可以使用Select
投影索引以创建结果:
var results = indices
.Where(...)
.Select(index => new { index.X, index.Y, Result = ... });
当您将代码转换为此表单并确保它适用于小型数据集时,您可以使用PLINQ通过插入Select
并行地在AsParallel
中运行计算:
var results = indices
.Where(...)
.AsParallel()
.Select(index => new { index.X, index.Y, Result = ... })
.ToList();
在你的问题中,你谈到订单的重要性。您可以使用AsOrdered
:
var results = indices
.Where(...)
.AsParallel()
.AsOrdered()
.Select(index => new { index.X, index.Y, Result = ... })
.ToList();
但是,for循环的“body”仍然没有特定的顺序并行执行。只有在ToList
创建列表时才会排序的最终结果。如果您提到的订单的重要性意味着您的for循环体中使用了可变状态,那么您将无法使用PLINQ。
这种使用PLINQ的方法并不是特别有效。如果必须处理1,000,000个单元格,则此代码将分配1,000,000个对象来存储单元格的索引。但是,似乎处理时间而不是内存分配和垃圾收集限制了你的计算。
如果您使用类似Parallel.For
的内容来并行计算,那么您可以避免分配的开销,但之后您将使用TPL而不是PLINQ。
答案 1 :(得分:-1)
使用下面的代码,您可以使用您的集合代替列表。如果您需要任何帮助,请告诉我:
List<string> lst = new List<string>();
foreach (var item in lst.AsParallel())
{
foreach (var data in item)
{
}
}