9

1つの長いコンストラクターで多くの計算を行う「MyComputation」というクラスがあります。(ディスクI / Oやネットワーク操作なしで)単独で実行すると、通常、実行に約20ミリ秒かかります。このクラスの約100個のインスタンスは、「ComputeParent」などの親クラスによって作成されます。このクラスは、それらを作業項目としてThreadPoolにキューに入れます。

ThreadPool.QueueUserWorkItem(myComputationCall, my_computation_data);

「myComputationCall」は次のようになります。

    public static void myComputationCall(Object my_computation_data)
    {
        try
        {
            MyDataObject data = (MyDataObject)my_computation_data;

            var computation_run = new MyComputation(data.parameter1, data.parameter2);

            data.result = computation_run.result;
        }
        finally
        {
            if (Interlocked.Decrement(ref num_work_items_remaining) == 0)
                done_event.Set();
        }
    }

done_eventは静的なManualResetEventです。

    private static ManualResetEvent done_event;

    ...

    done_event = new ManualResetEvent(false);

さまざまな入力パラメーターに対して、ComputeParentを約500回実行します。だから私はたくさんのネストされたクラスを持っています。問題は、ComputeParentの実行にかかる時間が徐々に長くなることです。特定のComputeParentを実行するのにかかる時間にはある程度のばらつきがありますが、時間はかなり着実に増加します(幾何学的には、連続する各反復はより長い時間かかります)。

プログラムのメモリ消費量は非常に高いですが(〜300MB)、時間の経過とともに目立って増加することはありません。8つの論理コアを備えたコンピューターで実行されており、プロセッサーの使用は非常にバースト的であるようです。他に何が問題に関連しているのかわかりません。

ComputeParentをバッチファイルで実行する必要はありませんが、これを実行しても問題は発生しないようです。

4

2 に答える 2

3

ThreadPoolで使用可能なスレッドの数が0になり、新しい作業項目を追加し続けると、新しく追加された作業項目は「待機」します。これは、ComputeParentが「myComputationCall」のインスタンスを待機することを意味します。ComputeParentをどんどん起動すると、それらの平均実行時間が長くなります。

于 2012-05-25T07:34:26.990 に答える
0

この質問は回答済みです。すべてのポスターに感謝します。

同様の問題を抱えている他の人には、ヘンクが提案したタスク並列ライブラリを提案します。

于 2013-01-07T14:13:43.563 に答える