我正在尝试检查以下代码的性能,但每次进行顺序操作时都会提供比fork join更好的性能。
问题我想找到最大整数:
public class GetMaxIntegerProblem {
private final int[] intArray;
private int start;
private int end;
private int size;
public GetMaxIntegerProblem(int[] intArray, int start, int end) {
super();
this.intArray = intArray;
this.start = start;
this.end = end;
size = end - start;
}
public int getMaxSequentially() {
int max = Integer.MIN_VALUE;
for (int i = start; i < end; i++) {
int n = intArray[i];
max = n > max ? n : max;
}
return max;
}
public int getSize() {
return size;
}
public GetMaxIntegerProblem getMaxIntegerSubProblem(int subStart, int subEnd) {
return new GetMaxIntegerProblem(this.intArray, start + subStart, start + subEnd);
}
}
我对fork join的操作:
import java.util.concurrent.RecursiveAction;
public class GetMaxIntegerAction extends RecursiveAction {
private final int threshold;
private final GetMaxIntegerProblem problem;
private int result;
public GetMaxIntegerAction(int threshold, GetMaxIntegerProblem problem) {
super();
this.threshold = threshold;
this.problem = problem;
}
@Override
protected void compute() {
if (problem.getSize() < threshold) {
result = problem.getMaxSequentially();
} else {
int midPoint = problem.getSize() / 2;
GetMaxIntegerProblem leftProblem = problem.getMaxIntegerSubProblem(0, midPoint);
GetMaxIntegerProblem rightProblem = problem.getMaxIntegerSubProblem(midPoint + 1, problem.getSize());
GetMaxIntegerAction left = new GetMaxIntegerAction(threshold, leftProblem);
GetMaxIntegerAction right = new GetMaxIntegerAction(threshold, rightProblem);
invokeAll(left, right);
result = Math.max(left.result, right.result);
}
}
}
我的主要测试程序:
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
public class GetMaxIntegerMain {
public GetMaxIntegerMain() {
// TODO Auto-generated constructor stub
}
private Random random = new Random();
private void fillRandomArray(int[] randomArray) {
for (int i = 0; i < randomArray.length; i++) {
randomArray[i] = random.nextInt(10000);
}
}
/**
* @param args
*/
public static void main(String[] args) {
GetMaxIntegerMain mainexcution=new GetMaxIntegerMain();
int arrayLength = 10_00_000;
int array[] = new int[arrayLength];
mainexcution.fillRandomArray(array);
GetMaxIntegerProblem problem=new GetMaxIntegerProblem(array, 0, array.length);
//No. of times sequential &
//Parallel operation should be performed to warm up HotSpot JVM
final int iterations = 10;
long start = System.nanoTime();
int maxSeq=0;
for (int i = 0; i < iterations; i++) {
maxSeq=problem.getMaxSequentially();
}
long endSeq=System.nanoTime();
long totalSeq=endSeq-start;
System.out.println(" time for seq "+(endSeq-start));
System.out.println("Number of processor available: " + Runtime.getRuntime().availableProcessors());
//Default parallelism level = Runtime.getRuntime().availableProcessors()
int threads=Runtime.getRuntime().availableProcessors();
ForkJoinPool fjpool = new ForkJoinPool(64);
long startParallel = System.nanoTime();
for (int i = 0; i < iterations; i++) {
GetMaxIntegerAction action=new GetMaxIntegerAction(5000, problem);
fjpool.invoke(action);
}
long endParallel = System.nanoTime();
long totalP=endParallel-startParallel;
System.out.println(" time for parallel "+totalP);
double speedup=(double)(totalSeq/totalP);
System.out.println(" speedup "+speedup);
System.out.println("Number of steals: " + fjpool.getStealCount() + "\n");
}
}
每次运行此代码时,我都会获得forkjoin特定代码需要400%的时间。我尝试了各种阈值组合,但我没有取得成功。
我在Windows 10 Intel Core i3处理器3.3 GHz 64位上运行此代码。
如果有人可以就这个问题提供一些指示,那将会很有帮助。
答案 0 :(得分:0)
在使用fork join时,很多情况下你不应该期望更好的性能,因为分叉和连接的开销可能会变得非常大。例如,请参阅此演讲(主要是下半部分)https://www.youtube.com/watch?v=2nup6Oizpcw