我需要使用大量的双精度数,并使用处理器密集型函数以块的形式处理它。
我原来的阵列非常大,大约有200MB的信号数据。
我需要将它们分成5000个双打,使用一个返回单个double的函数来处理那些具有处理器密集度的数学。需要每个函数结果来创建稍后使用的有序数组。
我认为这对于使用PLINQ的并行性来说是最佳的,但我不太清楚如何去做。
我写的天真实现看起来像这样:
var processedList = new List<double>();
var chunk = new List<double>;
foreach (var rawSample in drop.RawSamples)
{
chunk.Add(rawSample);
if (chunk.Count == 5000)
{
// Do long processing here
processedList.Add(LongProcessingFunction(chunk));
chunk.Clear();
}
}
// Do something later with the list of processed values.....
那么,我从哪里开始使用PLINQ?我需要能够使用处理器的所有核心来执行长时间的密集功能。
我看到IEnumerable有一个Take(n)函数.....我可以使用它吗?
我可以在这里使用AsParallel吗?
谢谢!
答案 0 :(得分:2)
首先,如果你正在处理这些数据,你应该避免逐个元素地处理它,如果可以的话。在您的代码中,您可以通过以5000为增量迭代整数并使用Array.Copy()
之类的东西来实现。
或者更好的是,根本不做任何复制,让LongProcessingFunction
接受一个数组(或IList<T>
或IReadOnlyList<T>
,如果你在.Net 4.5;但是使用接口确实有一些开销)和该数组的偏移量。
如果您想要使代码平行,可以将ParallelEnumerable.Range()
与AsOrdered()
一起使用(这需要以正确的顺序生成结果)和Select()
:
double[] result = ParallelEnumerable.Range(0, drop.RawSamples.Length / chunkSize)
.AsOrdered()
.Select(i => LongProcessingFunction(drop.RawSamples, i * chunkSize))
.ToArray();
答案 1 :(得分:0)
我建议在索引源上实现一个分区程序,它会将你的源分成5000个元素的块。然后可以使用AsParallel
对它们中的每一个进行处理。
class Program
{
static void Main(string[] args)
{
IList<double> rawData = [Your raw data here];
IList<double> result =
rawData
.Partition(5000)
.AsParallel()
.AsOrdered()
.Select(chunk => LongProcessingFunction(chunk))
.ToList();
}
private static double LongProcessingFunction(IList<double> chunk)
{
throw new NotImplementedException();
}
}
public static class MyExtensions
{
public static IEnumerable<List<T>> Partition<T>(this IList<T> source, Int32 size)
{
for (int i = 0; i < Math.Ceiling(source.Count / (Double)size); i++)
{
yield return new List<T>(source.Skip(size*i).Take(size));
}
}
}