0

確率変数を使用して正規分布を生成する Wpf コードを作成しました。

using System.Threading.Tasks;
using System.Threading;


private void Button_Click(object sender, RoutedEventArgs e)
        {            .....


for (int t = 0; t < normalx.Count; t++)
            {
                normaly.Insert(t, (2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2)));
            }

...


}

これは連続コードです。

並列スレッドとして実行するには、これを次のように変更しました

Parallel.For(0, normalx.Count, t =>
            {
                normaly.Insert(t, (2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2)));
            });

ビルドは問題ありませんが、実行時にスレッド領域が 1 つだけです( normalx.Count/8<- 私の PC は i7 です)

作業して計算しました。

何が悪いの?

4

2 に答える 2

2

TPLは、並列ループに指定された数のスレッドを使用することを保証しません。可能ですが、ループ内で実行して単一のスレッドで実行するだけの作業量を考えると、追加のスレッドを開始するオーバーヘッドが大きすぎると判断される場合があります。

http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for.aspx

反復並行して実行される可能性のあるforループを実行します。

(強調鉱山)

カスタムパーティショナーを提供することで、複数のスレッドを強制できる場合があります(強制は必ずしも良い考えではありません)が、私はまだ試していません。

http://msdn.microsoft.com/en-us/library/dd560853.aspx

TPLは、「カスタムパーティショナーを提供したことは素晴らしいですが、各パーティションを1つのスレッドで順番に実行します」と自由に言うことができます。その点で現在の実装がどのように動作するかはわかりません。

アップデート

ヘンクのコメントを読み直して確認しましたが、最初にあなたの質問を正しく読んだかどうかはわかりません。

法線の一部だけが計算されたと言っていますか?その場合は、バッキングされているコレクションがnormalyスレッドセーフではないことが原因である可能性があります。

その場合は、計算を行い、それを一時変数に割り当ててからlock、実際の挿入の周りを使用することができます。これにより、コレクションに挿入するボトルネックが発生しますが、計算の並列処理は引き続き得られます。

于 2012-04-04T06:34:46.923 に答える
0

ほとんどの場合、normaly.Insert(t, ...)スレッドセーフではなく、実行したい操作ではない可能性があります。あなたがしたいことは、事前に必要なすべてのスロットを備えた空のデータ構造を作成し、それらを並列ループで埋めることです。これを行う方法は次のとおりです。

var temp = new double[normalx.Count];
Parallel.For(0, normalx.Count, t =>
    temp[t] = 2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) *
              Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2));
normaly = temp.ToList();
于 2012-04-04T06:54:15.013 に答える