3

一部のコードを.NET2から4にシフトし、とりわけTPLを利用しています。

この質問はSOのどこかで行われたに違いないと思いますが、見つかりませんでした。

TPLタスクを過剰にネストすると、パフォーマンスが低下する可能性があることを私は知っています。

for (int y=0; y < h; y++)
    for (int x=0; x < w; x++)
        grid [x, y] = ((x + 1) * (y + 1));

上記の外側または内側のループをTPLに置き換えますか?その理由は何ですか?そして、追加のレベルのネストがあった場合はどうなりますか?

これは、内側のループが置き換えられたコードです。私の場合、1秒もうまくいきました。

int w = 10000;
int h = 10000;
int [,] grid = new int [w, h];
int [] index = new int [w * h];
DateTime time = DateTime.Now;
ParallelOptions options = new ParallelOptions();

options.MaxDegreeOfParallelism = Environment.ProcessorCount;

time = DateTime.Now;
for (int y=0; y < h; y++)
{
    Parallel.For
    (
        0,
        w,
        options,
        x =>
        {
            grid [x, y] = ((x + 1) * (y + 1));
        }
    );
}
span = DateTime.Now.Subtract(time);
Console.WriteLine("Filled in " + span.TotalSeconds.ToString() + " seconds.");

time = DateTime.Now;
for (int y=0; y < h; y++)
{
    Parallel.For
    (
        0,
        w,
        options,
        (x, state) =>
        {
            if (grid [x, y] < index.Length)
            {
                index [grid [x, y]]++;
            }
            else
            {
                state.Break();
            }
        }
    );
}
span = DateTime.Now.Subtract(time);
Console.WriteLine("Indexed in " + span.TotalSeconds.ToString() + " seconds.");
4

3 に答える 3

4

に隣接していないのにメモリ内rect[x,]で隣接しているため、内側のループを並列化するとパフォーマンスが向上します。したがって、外側のループを並列化すると、同じメモリスペースでの競合が増え、処理速度が低下します。rect[x+1,]rect[,y]rect[,y+1]

それはさておき、外側のループの並列化はより高速であるはずなので、内側と外側のループを切り替えてから外側のループで実行するParallel.Forと、現在のテストのいずれよりも優れたパフォーマンスが得られるはずです。

もう1つの注意点は、境界チェックにはいくらかコストがかかるため、大きな配列をループする代わりに、安全でないコード/ポインターを使用することで、パフォーマンスがいくらか向上することもわかります。

于 2012-07-29T21:02:53.203 に答える
0

外側のループ。内側のループを使用すると、外側のループよりも多くのクロススレッド通信が発生するためです。

于 2012-07-29T18:56:32.253 に答える
-1

ない!パフォーマンスの問題もありますか?あなたが提供したコードサンプルが本物である場合、パフォーマンスがはるかに優れているジャグ配列の恩恵を受けることができるようです。

于 2012-07-29T19:02:26.977 に答える