2017-02-08 1 views
-2

Я пытаюсь проверить выполнение следующего кода, но каждый раз, когда я получаю последовательную операцию, вы получаете лучшую производительность по сравнению с вилкой.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); 
    } 
} 

Мои действия для вилки присоединиться:

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% больше времени. Я пробовал с различной комбинацией порога, но я не достигаю успеха.

Я запускаю этот код на Процессор Intel Core i3 3.3 ГГц 64 бит на окнах 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

Смежные вопросы