2

私は JDK 7 の新機能、つまり Fork と Join を研究しています。Javadoc では、 aForkJoinTaskのコンテキストでのみ fork を行うことはできないと述べていますForkJoinPoolfork()ただし、メソッド呼び出しが新しいスレッドを作成するかどうかについては言及していません。

ForkJoinPoolワークスティーリング アルゴリズムを使用してスレッド間の作業のバランスを取りますが、実際に作成されるスレッドの数についてはどこにも言及されていません。

分断と支配の方法で分割する必要があるタスクがありますが、ForkJoinPoolこれらのスレッドを管理するオーバーヘッドのために、あまりにも多くのスレッドが作成され、実行のパフォーマンスが低下するのではないかと心配しています。

誰かがこれで私を助けることができますか?

4

1 に答える 1

0

fork は (必然的に) 新しいスレッドを作成しません。私のベンチマークでは、利用可能なコアごとに 1 つのスレッド + 1 つの余分なスレッドしか作成しません。ベンチマークの添付; main() から as を呼び出しFactorizer.factorize(71236789143834319L)ます。

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class Factorizer extends RecursiveTask<Long> {

static ForkJoinPool fjPool = new ForkJoinPool();
static final int sequentialThreshold = 10000;

private long number, low, high;

Factorizer(long number, long low, long high) {
    this.number = number; this.low = low; this.high = high;
}

private long factorize() {
    if ((number % 2) == 0) {
        return 2;
    }
    // ensures i is odd (we already know number is not even)
    long i = ((low % 2) == 0) ? low + 1: low;
    for (/**/; i < high; i+=2) {
        if ((number % i) == 0) {
            return i;
        }
    }
    return number;
}

@Override
protected Long compute() {

    // ugly debug statement counts active threads
    System.err.println(Thread.enumerate(
            new Thread[Thread.activeCount()*2]));

    if (high - low <= sequentialThreshold) {
        return factorize();
    } else {
        long mid = low + (high - low) / 2;
        Factorizer left = new Factorizer(number, low, mid);
        Factorizer right = new Factorizer(number, mid, high);
        left.fork();
        return Math.min(right.compute(), left.join());
    }
}

static long factorize(long num) {
    return fjPool.invoke(new Factorizer(num, 2, (long)Math.sqrt(num+1)));
}
}

注 - これは単なるテストでした。このコードを使用して、大きなものを真剣に因数分解しようとしないでください。

于 2012-07-16T10:34:57.487 に答える