2017-02-08 7 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.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"); 


    } 

} 

때마다 내가 실행하고 있습니다 :

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); 
     } 

    } 

} 

내 주요 프로그램 테스트 이 코드는 forkjoin 특정 코드가 400 % 더 많은 시간이 걸립니다. 나는 문턱의 다양한 조합으로 시도했지만 나는 성공하지 못하고있다.

이 코드는 에 실행 중입니다. Intel Core i3 프로세서 3.3GHz 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

포크 결합을 사용할 때 성능 향상이 기대되지 않는 경우가 많이 있습니다. 분기 및 결합의 오버 헤드가 상당히 커질 수 있기 때문입니다. 예를 들어,이 이야기 (대부분 하반부)를 참조하십시오. https://www.youtube.com/watch?v=2nup6Oizpcw