Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ExecutorService无性能增益递归行列式Java_Java_Multithreading_Performance_Recursion_Executorservice - Fatal编程技术网

ExecutorService无性能增益递归行列式Java

ExecutorService无性能增益递归行列式Java,java,multithreading,performance,recursion,executorservice,Java,Multithreading,Performance,Recursion,Executorservice,我读过类似的问题,其中问题是使用同步方法(如Math.random()),或者工作量太小,无法证明开销的合理性,但我认为这里的情况并非如此 我的处理器有4个物理/8个逻辑核。在一次预热后,我用n=1测试以下代码;2.3.4.11x11矩阵上的8个 ExecutorService pool = Executors.newFixedThreadPool(n); long startTime = System.currentTimeMillis(); double result = pool.subm

我读过类似的问题,其中问题是使用同步方法(如Math.random()),或者工作量太小,无法证明开销的合理性,但我认为这里的情况并非如此

我的处理器有4个物理/8个逻辑核。在一次预热后,我用n=1测试以下代码;2.3.4.11x11矩阵上的8个

ExecutorService pool = Executors.newFixedThreadPool(n);
long startTime = System.currentTimeMillis();
double result = pool.submit(new Solver(pool, matrix)).get();
System.out.println(result);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);
执行分别需要:

1~15500 2 ~ 13500 - 14000 3 ~ 14300 - 15500 4 ~ 14500 - 19000 8~19000-23000

所以我得到了一个 用2点来增加动力, 几乎没有增加3, 有时几乎没有提振,但有时极端减速,4 以8%的速度完成减速

代码如下:

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public class Solver implements Callable<Double> {

    private ExecutorService pool;
    private double[][] matrix;


    public Solver(ExecutorService pool, double[][] matrix){
        this.pool = pool;
        this.matrix = matrix;
    }

    public double determinant(double[][] matrix) {
        if (matrix.length == 1)
            return (matrix[0][0]);

        double coefficient;
        double sum = 0;
        int threadsCount = ((ThreadPoolExecutor) pool).getMaximumPoolSize();
        ArrayList<Double> coefficients = new ArrayList<Double>();
        ArrayList<Future<Double>> delayedDeterminants = new ArrayList<Future<Double>>();

        for (int k = 0; k < matrix.length; k++) {
            double[][] smaller = new double[matrix.length - 1][matrix.length - 1];
            for (int i = 1; i < matrix.length; i++) {
                for (int j = 0; j < matrix.length; j++) {
                    if (j < k)
                        smaller[i - 1][j] = matrix[i][j];
                    else if (j > k)
                        smaller[i - 1][j - 1] = matrix[i][j];
                }
            }
            coefficient = ((k % 2 == 0) ? 1 : -1) * matrix[0][k];
            if (((ThreadPoolExecutor) pool).getActiveCount() < threadsCount
                    && matrix.length > 5) {
                coefficients.add(coefficient);
                delayedDeterminants.add(pool.submit(new Solver(pool, smaller)));
            } else
                sum += coefficient * (determinant(smaller));
        }

        try {
            for (int i = 0; i < coefficients.size(); i++)
                sum += coefficients.get(i) * delayedDeterminants.get(i).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        return (sum);
    }

    @Override
    public Double call() throws Exception {
        return determinant(matrix);
    }

}
import java.util.ArrayList;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Future;
导入java.util.concurrent.ThreadPoolExecutor;
公共类解算器实现了可调用{
私人服务池;
私有双[]矩阵;
公共解算器(ExecutorService池,双[]矩阵){
this.pool=pool;
这个矩阵=矩阵;
}
公共双行列式(双[]矩阵){
如果(矩阵长度==1)
返回(矩阵[0][0]);
双系数;
双和=0;
int threadscont=((ThreadPoolExecutor)pool.getMaximumPoolSize();
ArrayList系数=新的ArrayList();
ArrayList delayedDeterminants=新的ArrayList();
对于(int k=0;kk)
较小的[i-1][j-1]=矩阵[i][j];
}
}
系数=((k%2==0)?1:-1)*矩阵[0][k];
if(((ThreadPoolExecutor)pool).getActiveCount()5){
系数。加(系数);
delayedDeterminants.add(pool.submit)(新的求解器(pool,更小));
}否则
总和+=系数*(行列式(较小));
}
试一试{
对于(int i=0;i
处理这种分治算法的一般方法是在单个线程中降低到某一级别,直到有足够的独立任务,然后在ExecutorService上调度所有这些任务,让更多级别的递归在同一任务中执行。例如,在下一层中,您有121个子矩阵要计算其行列式,因此向ExecutorService提交121个任务。或者再上一层,获得12100个子问题并提交所有这些问题

轮询ExecutorService以获取活动任务计数可能不是最好的主意。创建一个
newFixedThreadPool(4)
或您想要测试的任意数量的线程,并让ExecutorService管理任务的执行。如果您试图完成的是工作窃取,那么我强烈建议您花一些时间熟悉Fork/Join框架,它可以自动管理工作窃取。它被设计来精确地处理您的任务


另一件与问题没有直接关系的事情是:您必须重新设计代码,以便所有计算都只使用一个2D数组。1D数组会更好。

处理这种分治算法的一般方法是在单个线程中降低到某个级别,直到有足够的独立任务,然后在ExecutorService上调度所有这些任务,让更多级别的递归在同一个任务中执行。例如,在下一层中,您有121个子矩阵要计算其行列式,因此向ExecutorService提交121个任务。或者再上一层,获得12100个子问题并提交所有这些问题

轮询ExecutorService以获取活动任务计数可能不是最好的主意。创建一个
newFixedThreadPool(4)
或您想要测试的任意数量的线程,并让ExecutorService管理任务的执行。如果您试图完成的是工作窃取,那么我强烈建议您花一些时间熟悉Fork/Join框架,它可以自动管理工作窃取。它被设计来精确地处理您的任务


另一件与问题没有直接关系的事情是:您必须重新设计代码,以便所有计算都只使用一个2D数组。1D阵列会更好。

1&2)11x11是一个小矩阵,但计算量不小。该算法具有可怕的复杂性(类似于(n!)^2)。我用12x12矩阵试过,每次测试需要3分钟。100x100矩阵实际上需要数百年的时间。3) 不完全确定您的意思,如果是getActiveCount()行,那么想法是如果有空闲线程,我在线程中运行递归任务,否则我在当前线程中运行它。请注意,我不能总是在另一个线程中运行它,因为它是递归的,所以一个线程在其所有递归调用的线程都被调用之前是不会空闲的。@ndn啊,是的,现在它又回到我身边了。。。它确实在计算上爆炸了。处理这种分治算法的一般方法是在单个线程中下降到某个级别,直到有足够的独立任务,然后调度