1

.NETFramework4.0で並列forループを利用しようとしています。ただし、結果セットにいくつかの要素が含まれていないことに気付きました。

以下のようなコードスニペットがあります。lhs.ListDataはnull許容doubleのリストであり、rhs.ListDataはnull許容doubleのリストです。

int recordCount = lhs.ListData.Count > rhs.ListData.Count ? rhs.ListData.Count : lhs.ListData.Count;

List<double?> listResult = new List<double?>(recordCount);
var rangePartitioner = Partitioner.Create(0, recordCount);  

Parallel.ForEach(rangePartitioner, range =>
                    {
                        for (int index = range.Item1; index < range.Item2; index++)
                        {
                            double? result = lhs.ListData[index] * rhs.ListData[index];
                            listResult.Add(result);
                        }
                    });

lhs.ListDataの長さは7964、rhs.ListDataの長さは7962です。「*」操作を実行すると、listResultの出力は7867のみになります。両方の入力リストにnull要素があります。

実行中に何が起こっているのかわかりません。結果セットに表示される要素が少なくなる理由はありますか?ご意見をお聞かせください...

4

3 に答える 3

2

これを行う正しい方法は、LINQの拡張機能を使用することIEnumerable.AsParallel()です。それはあなたのためにすべてのパーティショニングを行い、PLINQのすべては本質的にスレッドセーフです。Zip与えられた関数に基づいて、2つのコレクションを1つにまとめるという別のLINQ拡張機能があります。ただし、これは2つのリストのうち短い方の長さであり、長い方ではないため、正確には必要ありません。これを行うのはおそらく簡単ですが、最初に2つのリストの短い方を、リストnullの最後にパディングして長い方のリストの長さに拡張します。

IEnumerable<double?> lhs, rhs;    // Assume these are filled with your numbers.
double?[] result = System.Linq.Enumerable.Zip(lhs, rhs, (a, b) => a * b).AsParallel().ToArray();

これがMSDNページZipです:

http://msdn.microsoft.com/en-us/library/dd267698%28VS.100%29.aspx

于 2012-10-09T02:42:42.077 に答える
0

List<double?>結果を保存するために使用していますが、Addメソッドはスレッドセーフではありません。Add明示的なインデックスを使用して、(を呼び出す代わりに)結果を格納できます。

listResult[index] = result;
于 2012-10-09T02:33:51.160 に答える
0

これはおそらく、List<T>(eg Add) に対する操作がスレッド セーフではないためです。結果は異なる場合があります。回避策としてロックを使用できますが、パフォーマンスが大幅に低下します。

結果リストの各項目を 2 つの入力リストの対応するインデックスにある項目の積にしたいだけのように見えますが、代わりに PLINQ を使用するのはどうでしょうか。

var listResult = lhs.AsParallel()
                    .Zip(rhs.AsParallel(), (a,b) => a*b)
                    .ToList();

ここで並列処理を選択した理由がわかりません。これが必要な場合でもベンチマークを行います。これは本当にアプリケーションのボトルネックですか?

于 2012-10-09T02:20:45.713 に答える