使用 ThreadPool 并行化矩阵乘法

Using ThreadPool for parallelisation of Matrix Multiplication

我正在尝试并行矩阵乘法。

我通过在单独的线程中计算矩阵 C 的每个单元格实现了并行化。 (我希望我做对了)。

我的问题是使用线程池是否是创建线程的最佳方式。 (对不起,我对此不熟悉,有人建议这样做)

另外,与此相比,我是否会发现使用顺序版本的程序进行计算所花费的时间有很大差异?

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ParallelMatrix {

public final static int N = 2000; //Random size of matrix
public static void main(String[] args) throws InterruptedException {

    long startTime = System.currentTimeMillis();

    //Create and multiply matrix of random size N.   
    double [][] a = new double [N][N];
    double [][] b = new double [N][N];
    double [][] c = new double [N][N];

    int i,j,k;

    for(i = 0; i < N ; i++) {
        for(j = 0; j < N ; j++){
            a[i][j] = i + j;
            b[i][j] = i * j;
        }

        ExecutorService pool = Executors.newFixedThreadPool(1);
        for(i = 0; i < N; i++) {
            for(j = 0; j < N; j++) {  
                pool.submit(new Multi(N,i,j,a,b,c));
            }
        }
        pool.shutdown();
        pool.awaitTermination(1, TimeUnit.DAYS);
        long endTime = System.currentTimeMillis();
        System.out.println("Calculation completed in " +
             (endTime - startTime) + " milliseconds");

    }
    static class Multi implements Runnable {
        final int N;
        final double [][] a;
        final double [][] b;
        final double [][] c;
        final int i;
        final int j;

        public Multi(int N, int i, int j, double[][] a, double[][] b, double[][] c){
            this.N=N;
            this.i=i;
            this.j=j;
            this.a=a;
            this.b=b;
            this.c=c;
        }

        @Override
        public void run() {
            for(int k = 0; k < N; k++) 
                c[i][j] += a[i][k] * b[k][j];
        }
    }
}

您必须在调度开销、操作持续时间和可用内核数之间取得平衡。首先,根据可用内核数 newFixedThreadPool(Runtime.getRuntime().availableProcessors()).

调整线程池的大小

为了最大限度地减少调度开销,您希望将操作分成与您拥有的处理器一样多的独立任务(理想情况下执行时间相等)。

通常,您在切片中执行的操作越小,您的调度开销就越大。您现在拥有的(N 平方任务)的开销过大(您将创建并提交 2000 次 2000 次 Multi runnable,每个都做很少的工作)。