如何在Javaello的ForkJoin框架中使用多个Compute方法

发布于 2024-12-20 05:29:49 字数 3185 浏览 2 评论 0原文

我需要解决一个更简单的问题。我需要求解 1000 个随机 X 值和 1000 个随机 Y 值的并行求和。我正在使用java的Parallel ForkJoin框架。使用单一计算方法,不可能计算完全不同路线中的X值和Y值的总和。

更重要的是,我需要计算 X * Y 的总和。即 Σxiyi 但单个线程遍历的 X 值分配一个单独的任务,并且 Y 作为单独的任务插入到线程池中。那么如何才能同时将 X 和 Y 值相乘,即 X * Y ==> (X = 100,Y = 150)? 第一个线程在 X 上运行,第二个线程在 Y 上运行。

代码:

public class 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;
        }       
    }

}

I need a simpler problem to solve. I need to solve the parallel summation of 1000 random X values and 1000 random Y values. I am using Parallel ForkJoin framework of java. With the the usage of single compute method, it's not possible to compute the summation of X values and Y values in completely different routes.

More over I need to calculate Sum of X * Y. i.e Σxiyi BUT X values traversed by one single thread assigns a separate task, and Y is inserted into threadpool as separate task. So how is it possible to multiply both X and Y values simulatanouesly i.e X * Y ==> (X = 100, Y = 150)?
First Thread is operating on X and second on Y.

Code:

public class 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;
        }       
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人疚 2024-12-27 05:29:49

您应该在任务外部创建 2 个 int 数组 xsys 并作为任务的参数给出。所以你的构造函数

RegressionLineForkJoinTask(int a_start,int a_end)
会是
RegressionLineForkJoinTask(int a_start,int a_end, int[] vector),向量为 xsys
他们会以这种方式使用向量:

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 */
}

然后在相同的基础上,您可以使用以下构造函数使用两个向量来处理两个向量:
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 */
}

You should have your 2 int arrays xs and ys created outside your tasks and given as parameters on your tasks. So your constructor

RegressionLineForkJoinTask(int a_start,int a_end)
would be
RegressionLineForkJoinTask(int a_start,int a_end, int[] vector) with vector being xs or ys.
They would use vector that way:

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 */
}

Then on the same basis you can have a ProductRecursiveForkJoinTask working with two vectors with this constructor:
RegressionLineForkJoinTask(int a_start,int a_end, int[] vectorA, int[] vector B)

with this compute method:

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 */
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文