6

私は並列処理でいくつかのテストを実行していて、与えられた整数の行列が隣人に基づいて各位置の値を再計算するプログラムを作成しました。

CyclicBarrier部分的な問題が解決されたら、値がオーバーライドされず、結果をマージするためにa を使用しないように、マトリックスのコピーが必要でした。

CyclicBarrier cyclic_barrier = new CyclicBarrier(n_tasks + 1, new Runnable() {
    public void run() {
        ParallelProcess.mergeResult();
    }
});
ParallelProcess p = new ParallelProcess(cyclic_barrier, n_rows, r_cols); // init

各タスクにはマトリックスの一部が割り当てられます。行ごとに均等に分割しています。ただし、分割が正確ではない可能性があるため、最後の行に対応する小さな部分がスレッド プールに送信されないことがあります。

例:16行がありn_tasks = 4、問題がなければ、4 つすべてがプールに送信されます。しかし、そうでは18なく、最初の 16 件は送信されますが、最後の 2 件は送信されません。

したがって、このケースが発生した場合は提出を強制しています。まあ、実際には提出していませんが、このように作成した固定スレッド プールを使用しているためですExecutorService e = Executors.newFixedThreadPool(n_tasks)。プール内のすべてのスロットが占有され、スレッドがバリアによってブロックされているため (メソッドmybarrier.await()で呼び出されrunます)、プールに送信できなかったため、Thread.start().

ポイントに行きましょう。CyclicBarrierそのチャンクが残る可能性を考慮する必要があるため、パーティーの数を 1 つ増やす必要があります。

だが、もしこの事件が起こらなければ、私は結界を発動するのに一役不足だった。

私の解決策は何ですか?:

if (lower_limit != n_rows) { // the remaining chunk to be processed
    Thread t = new Thread(new ParallelProcess(lower_limit, n_rows));
    t.start();
    t.join();
}
else {
    cyclic_barrier.await();
}

cyclic_barrier.await()無理矢理バリアを張る裏ワザを使っているとごまかしているような気がします。

この問題に取り組むことができる他の方法はありますか?

4

1 に答える 1

1

これは CyclicBarriers に関するあなたの質問には答えませんが、Phaserの使用をお勧めできますか? mergeResultこれにはパーティーの数を含める機能があり、フェーズがトリップしたときに実行することもできます.

したがって、非同期計算を実行する前に、単純にregister. 次に、その計算内で、スレッドが に到着しますphaser。すべてのスレッドが到着すると、フェーズが進み、オーバーライドされたメソッドを呼び出すことができますonAdvance

提出物:

ParallelProcess process = new ParallelProcess(lower_limit, n_rows));
phaser.register();
executor.submit(process);

プロセッサ

public void run(){
   //do stuff
   phaser.arrive();
}

フェイザー

Phaser phaser = new Phaser(){
    protected boolean onAdvance(int phase, int registeredParties) {
        ParallelProcess.mergeResult(); 
        return true;
    }
}
于 2014-06-23T19:35:34.977 に答える