2

整数の 2 次元配列があります。2 次元配列のすべての列を合計する最適化された高速なコードを書きたいと思います。

LINQ/PLINQ/TASK 並列化を使用してこれを行うにはどうすればよいでしょうか?

元:

private int[,] m_indexes = new int[6,4]  { {367, 40, 74, 15},
                                           {535, 226, 74, 15}, 
                                           {368, 313, 74, 15},
                                           {197, 316, 74, 15}, 
                                           {27, 226, 74, 15},
                                           {194, 41, 74, 15} };
4

3 に答える 3

5

最も単純な並列実装:

 int[,] m_indexes = new int[6, 4]  { {367, 40, 74, 15},
                                     {535, 226, 74, 15}, 
                                     {368, 313, 74, 15},
                                     {197, 316, 74, 15}, 
                                     {27, 226, 74, 15},
                                     {194, 41, 74, 15} };
 var columns  = Enumerable.Range(0, 4);
 int[] sums = new int[4];
 Parallel.ForEach(columns, column => {
     int sum = 0;
     for (int i = 0; i < 6; i++) {
         sum += m_indexes[i, column];
     }
            sums[column] = sum;
 });

このコードは明らかに「一般化」できます (m_indexes.GetLength(0)と を使用m_indexes.GetLength(1))。

リンク:

var sums = columns.Select(
    column => {
        int sum = 0;
        for (int i = 0; i < 6; i++) {
            sum += m_indexes[i, column];
         } return sum; 
    }
).ToArray();

ここでパフォーマンスを最適化する必要がある場合は、ここで実際のデータをプロファイルしてください。

また、パフォーマンスの最適化に本当に関心がある場合は、行全体で合計できるように配列をロードしてみてください。そうすれば、キャッシュ パフォーマンスの局所性が向上します。

于 2011-09-12T20:30:38.733 に答える
1

簡単なLINQの方法:

var columnSums = m_indexes.OfType<int>().Select((x,i) => new { x, col = i % m_indexes.GetLength(1) } )
    .GroupBy(x => x.col)
    .Select(x => new { Column = x.Key, Sum = x.Sum(g => g.x) });

並列化する価値はないかもしれません。インデックスで配列にアクセスする必要がある場合は、境界チェックに数サイクルを費やすので、いつものようにパフォーマンスを測定してください。

于 2011-09-12T20:27:04.230 に答える
1

または多分 for なしで:

List<List<int>> m_indexes = new List<List<int>>()  { new List<int>(){367, 40, 74, 15},
new List<int>(){535, 226, 74, 15}, 
new List<int>(){368, 313, 74, 15},
new List<int>(){197, 316, 74, 15}, 
new List<int>(){27, 226, 74, 15},
new List<int>(){194, 41, 74, 15} };

var res = m_indexes.Select(x => x.Sum()).Sum();
于 2011-09-12T20:37:24.277 に答える