1

スレッド ローカル変数で Parallel.For を使用するように記述されたコードがいくつかあります。これは基本的には大きな配列の合計ですが、配列の要素は合計と同時に for ループで明示的に計算されます。

私が抱えている問題は、スレッドローカル変数が非常に重いオブジェクトであることです。200 MB のメモリを占有することは珍しくありません。プログラムのメモリ使用量が 2 GB に急上昇し、その後 GC がそれを 200 MB に戻し、上下に移動することに気付きました。これは、多くの一時メモリが割り当てられていることを示しています。いくつかのスレッド ローカル変数が必要なので、それらを構造体オブジェクトにラップしました。これにより、Console.WriteLine をコンストラクターに追加できるようになり、多くのオブジェクトが作成されていることがわかりましたが、マシンのコアごとに 1 つの構成しか期待していませんでした。正確に (numberOfCores) スレッドを作成し、それらだけを最後まで保持するにはどうすればよいですか?

追加した

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 2;

これはほんのわずかしか役に立ちませんでした。まだ構造体の構造が多すぎます。options.TaskScheduler でできることはありそうですが、その威力がどこまでなのかがよくわかりません。自分で巻けそうで、ちょっと怖いくらいです。できればやりたくない。

これが私のプログラムのコードの関連セクションです。

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 2;

Parallel.For<ThreadLocalData>(0, m, options,
    // Thread local variable initialization
    () => new ThreadLocalData(new DenseMatrix(r * r, r * r, 0),
                              new DenseMatrix(r * r, r * r, 0),
                              new DenseMatrix(r, r, 0)),
    // Per-thread routine
    (row, loop, threadLocalData) =>
    {
        threadLocalData.kronProductRight.Clear();
        for (int column = 0; column < n; ++column)
        {
            if ((int)E[row, column] == 1)
                threadLocalData.kronProductRight.Add(Yblocks[column], threadLocalData.kronProductRight);
        }
        MathNetAdditions.KroneckerProduct(Xblocks[row], threadLocalData.kronProductRight, threadLocalData.kronProduct);
        threadLocalData.subtotal.Add(threadLocalData.kronProduct, threadLocalData.subtotal);
        return threadLocalData;
    },
    (threadLocalData) =>
    {
        lock (mutex)
        A.Add(threadLocalData.subtotal, A);
    }
);
4

2 に答える 2

1

この記事をチェックしてくださいhttp://blogs.msdn.com/b/pfxteam/archive/2010/10/21/10079121.aspx特にParallelに関する部分。初期化デリゲートが高価なときにパフォーマンスの問題が発生した場合。

上記のコードを見るとわかりにくいですが、ThreadLocalDataの計算/データ部分をステートフル/変更の側面から分離できるはずです。理想的には、不変バージョンのThreadLocalDataへの参照を、数値を処理しているものに渡すでしょう。そうすれば、何があっても、1つのインスタンスを処理するだけです。

于 2012-05-05T09:07:07.927 に答える
0

私はあなたの質問の詳細には入っていません(そして、phoogが指摘したようにあなたは間違った質問をしているようです)が、あなたの特定の質問に答えるために:

正確に (numberOfCores) スレッドを作成し、それらだけを最後まで保持するにはどうすればよいですか?

まさにこれを行うスケジューラがあります:

http://blog.abodit.com/2010/11/task-parallel-library-a-scheduler-with-priority-apartment-state-and-maximum-degree-of-parallelism/

于 2012-05-05T00:09:32.717 に答える