-2
我想檢查下面的代碼的性能,但每次我順序操作相比,叉連接提供更好的性能。叉連接不給予更好的性能
問題,我想找到最大的整數:
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);
}
}
我對叉行動加入:
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%的時間。我嘗試了各種門檻組合,但我沒有獲得成功。
我正在運行此代碼英特爾酷睿i3處理器3.3 GHz 64位的Windows 10。
如果有人能夠提供關於這個問題的一些指導,這將是很大的幫助。
您正在使用不恰當的方式來評估性能。這應該是微觀基準測試。 – Andremoniy
http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Andremoniy
'new ForkJoinPool(64);'?要麼你跑得很野獸,要麼你誤解了FJP的工作原理。 – Kayaman