Как использовать более одного метода Compute в ForkJoin Framework Javaello - PullRequest
0 голосов
/ 09 декабря 2011

Мне нужно решить более простую проблему. Мне нужно решить параллельное суммирование 1000 случайных значений X и 1000 случайных значений Y. Я использую Parallel ForkJoin фреймворк Java. С использованием метода одиночного вычисления невозможно вычислить суммирование значений X и Y на совершенно разных маршрутах.

Более того, мне нужно вычислить сумму X * Y. Т.е. Σxiyi НО значения X, пройденные одним потоком, назначают отдельную задачу, а Y вставляется в пул потоков как отдельная задача. Так как же можно одновременно умножить значения X и Y, т. Е. X * Y ==> (X = 100, Y = 150)? Первый поток работает на X, а второй на Y.

Код:

открытый класс RegressionLineForkJoin {

//private static final ForkJoinPool forkJoinPool = new ForkJoinPool( 2 );         // use only 2 processors

private static Random r = new Random( );    
private static final int NR_OF_VALUES = 1000;      // X & Y VALUES
private static final int THRESHOLD = 100; // need to calculate Threshold value.

    private static class RegressionLineForkJoinTask extends RecursiveTask<Integer>
    {
        private int m_Start;
        private int m_End;

        public RegressionLineForkJoinTask(int a_start,int a_end)
        {
            this.m_Start = a_start;
            this.m_End = a_end;
        }
        public Integer compute()
        {       
            Integer Sum = 0;
            if(this.m_End - this.m_Start < THRESHOLD)
            {
                calculateSum(this.m_Start,this.m_End);
            }
            else
            {
                int split  = (this.m_Start + this.m_End)/2;

                RegressionLineForkJoinTask oRegressionLineTask_1  = new RegressionLineForkJoinTask(this.m_Start , split);
                RegressionLineForkJoinTask oRegressionLineTask_2  = new RegressionLineForkJoinTask( split+1 , this.m_End);

                // Invoke the tasks in parallel 
                invokeAll(oRegressionLineTask_1,oRegressionLineTask_2);

                Sum += oRegressionLineTask_1.join(); 
                Sum += oRegressionLineTask_2.join();

                //Sum

            }//end of else
            return Sum;
        }
        public static void main(String[ ] args)
        {
            RegressionLineForkJoinTask oRegressionLineForkJoinTask_X = new RegressionLineForkJoinTask( 0,NR_OF_VALUES );
            RegressionLineForkJoinTask oRegressionLineForkJoinTask_Y = new RegressionLineForkJoinTask( 0,NR_OF_VALUES );

            Integer Sum_X_Values =  forkJoinPool.invoke(oRegressionLineForkJoinTask_X);
            Integer Sum_Y_Values =  forkJoinPool.invoke(oRegressionLineForkJoinTask_Y);

            System.out.println("in main after forkjoin.invoke()");
        }
        private static double nextRandomFunctionValue(int a_startInex,int a_endIndex)
        {
            double randomValue = 0.0;
            randomValue = a_startInex + ( a_endIndex - a_startInex ) * r.nextDouble( ); 

            return randomValue;

        }//end of nextRandomFunctionValue
        private static double  calculateSum(int a_startIndex, int a_endIndex)
        {
            double sumValue = 0.0;
            double RandomeValue = 0.0;

            for(int index = a_startIndex; index< a_endIndex; index++)
            {                   
                RandomeValue = nextRandomFunctionValue(a_startIndex,a_endIndex);
                sumValue += RandomeValue;

            }//end of for
            return sumValue;
        }       
    }

}

1 Ответ

0 голосов
/ 21 августа 2012

Вам необходимо создать 2 массива int xs и ys вне ваших задач и указать их как параметры для ваших задач. Итак, ваш конструктор

RegressionLineForkJoinTask(int a_start,int a_end) было бы RegressionLineForkJoinTask(int a_start,int a_end, int[] vector) с вектором xs или ys. Они будут использовать vector таким образом:

public Integer compute() {       
    int sum = 0;
    if(this.m_End - this.m_Start < THRESHOLD) {
       for (int i = this.m_Start; i < this.m_End; i++)
         sum += this.m_vector[i];
    } /* else split task as before */
}

Тогда на той же основе вы можете иметь ProductRecursiveForkJoinTask, работающий с двумя векторами с этим конструктором: RegressionLineForkJoinTask(int a_start,int a_end, int[] vectorA, int[] vector B)

с этим методом вычисления:

public Integer compute() {       
    int sum = 0;
    if(this.m_End - this.m_Start < THRESHOLD) {
       for (int i = this.m_Start; i < this.m_End; i++)
         sum += this.m_vectorA[i] * this.m_vectorB[i];
    } /* else split task as before */
}
...