1

double の大きな配列を取得し、プロセッサを集中的に使用する関数を使用してチャンクで処理する必要があります。

私の元の配列は非常に大きく、約 200MB の倍の信号データです。

それぞれ 5000 個の double のチャンクで取得し、単一の 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 を使用できますか?

ありがとう!

4

2 に答える 2

2

まず、この量のデータを処理している場合は、可能であれば、要素ごとに処理することは避けてください。あなたのコードでは、5000刻みで整数を繰り返し、。のようなものを使用することでそれを行うことができますArray.Copy()

または、さらに良いことに、コピーをまったく行わずにLongProcessingFunction、配列(または、 .Net 4.5を使用している場合は、、IList<T>または、ですが、インターフェイスを使用するとオーバーヘッドが発生します)とその配列へのオフセットを受け入れます。IReadOnlyList<T>

次に、コードを並列化したい場合は、ParallelEnumerable.Range()with AsOrdered()(結果を正しい順序にするために必要)とSelect():を使用できます。

double[] result = ParallelEnumerable.Range(0, drop.RawSamples.Length / chunkSize)
    .AsOrdered()
    .Select(i => LongProcessingFunction(drop.RawSamples, i * chunkSize))
    .ToArray();
于 2012-07-13T10:23:23.750 に答える
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));
        }
    }
}
于 2012-07-13T10:22:33.650 に答える