2017-02-08 20 views
-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

如果有人能夠提供關於這個問題的一些指導,這將是很大的幫助。

+0

您正在使用不恰當的方式來評估性能。這應該是微觀基準測試。 – Andremoniy

+0

http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Andremoniy

+3

'new ForkJoinPool(64);'?要麼你跑得很野獸,要麼你誤解了FJP的工作原理。 – Kayaman

回答

0

有很多情況下,使用fork連接時不應該期望獲得更好的性能,因爲fork和join的開銷可能會相當大。例如,請參閱此對話(主要是下半部分)https://www.youtube.com/watch?v=2nup6Oizpcw