5

次のスニペットを書きました。

static private int counter;

    public void compute()
    {
        if (array.length<=500)
        {

            for(int i = 0;i<array.length;i++){
                counter++;
                System.out.println("Ciao this is a recursive action number"+ counter+Thread.currentThread().getName()); 
            }
        }
        else{
        int split = array.length/2;
        RecursiveActionTry right = new RecursiveActionTry(split);
        RecursiveActionTry left = new RecursiveActionTry(split);
        invokeAll(right, left);

渡した 2 つのオブジェクトinvokeAll()のうちの 1 つを自動的にフォークすることがわかります。RecursiveActionTry私のラップトップには 2 つのコアしかありません。4 つのコアがあり、4 つのタスクを起動した場合はどうなりinvokeAll(right, left, backward, forward);ますか?4 つのコアすべてを使用しますか? コアが2つしかないのでわかりません。

また、舞台裏で invokeAll(right, left)compute()が最初の引数 (右) とfork + join2 番目の引数 (左) を呼び出すかどうかも知りたいです。(RecursiveTask 拡張機能のように)。そうでなければ、並列処理を使用しないでしょうか? ちなみに、2 つ以上の引数がある場合はcompute()、最初の引数を呼び出して、他のすべての引数をフォークしますか?

前もって感謝します。

4

2 に答える 2

5

invokeAll()異なるスレッドで独立して実行される多数のタスクを呼び出します。これにより、スレッドごとに異なるコアを使用する必要はありませんが、スレッドごとに異なるコアが使用可能であれば、それらを使用できます。詳細は基盤となるマシンによって処理されますが、基本的に (単純に) 使用可能なコアがスレッドよりも少ない場合は、スレッドをタイム スライスして、あるコアで 1 つのコアを一定時間実行し、次に別のコアを実行し、次に別のコアを実行できるようにします (ループで。)

ちなみに、2 つ以上の引数がある場合は、最初の引数で compute() を呼び出し、他のすべてで fork を呼び出しますか?

それはcompute()すべての引数でありcompute()、ワーカーのしきい値が満たされていない場合はデリゲートしてフォークし、完了したら計算に参加するのはメソッドの責任です。(ただし、2 つ以上の方法で分割することはまれです。フォーク結合は通常、必要に応じてワークロードを 2 つに分割する再帰ごとに機能します。)

于 2013-06-03T12:16:29.607 に答える
0

タスクとワーカー スレッドは別のものです。

WorkerThreads は ForkJoinPool によって管理され、デフォルトのコンストラクターを使用する場合は、に従って WorkerThreads を開始しますRuntime.getRuntime().availableProcessors()

ただし、タスクは自分で作成/管理します。複数のコアをビジー状態にするには、いくつかのタスクを開始する必要があります。それぞれを 2 つの部分または N 個の部分に分割できます。1 つの部分が直接実行されている間、他の部分は待機キューに入れられます。プールからの他の WorkerThreads がアイドル状態で、実行する作業がない場合、それらはフォークされた保留中のタスクをキューから「盗み」、並行して実行することになっています。

8 つのコア/WorkerThread をビジー状態にするために、一度に 8 つのタスクを呼び出す必要はありません。すべての WorkerThread が飽和するまで、少なくとも 2 つのタスクにフォークするだけで十分です (再帰的に)。したがって、コアの数が多い場合も少ない場合もコードを調整する必要はなく、タスクは WorkerThread の管理についてまったく心配する必要はありません。

最後に、invokeAll() または join() は、すべてのタスクが実行された後に戻ります。

于 2013-06-05T12:12:51.397 に答える