使矩阵乘法并行工作 java

Making a matrix multiplication work in parallel java

我根据所学创建矩阵乘法的知识创建了这段代码。

但我想并行处理这段代码,以便它可以在多个线程上运行。

有人可以 help/do 这个给我吗?我不太确定该怎么做!

已更新:

public class ParallelMatrix {
    public final static int N = 1000; //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(10);
        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];
        }
    }
}

您可以在单独的线程中计算矩阵 C 的每个单元格,例如:

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

    @Override
    public void run() {
        for (int k = 0; k < N; k++)
            c[i][j] += a[i][k] * b[k][j];
    }
}
ExecutorService pool = ...;
for (int i = 0;...)
for (int j = 0;...)
pool.submit(new Multi(N, i, j, a, b, c));

pool.shutdown();
pool.awaitTermination(1, TimeUnit.DAYS);

虽然对整列或整行执行此操作更有意义。

FWIW 这里是使用 Java 流 API 的替代方法。可能有更好的方法来实现并行矩阵乘法,尤其是使用 BLAS 库和 GPU 实现(如 jcuBLAS)。但是如果你需要香草 Java 那么这将是一个选项。

static double[][] multiplyStreams(double[][] a, double[][] b) {
  assert a.length == b.length;
  assert a.length > 0;
  assert a[0].length == b[0].length;
  assert a.length == a[0].length; // just work on square matrices

  int N = a.length;

  double[][] result = new double[N][N];

  IntStream.range(0, N).parallel().forEach(i ->
    IntStream.range(0, N).parallel().forEach(j ->
      IntStream.range(0, N).forEach(k ->
        result[i][j] += a[i][k] * b[k][j]
      )
    )
  );

  return result;
}

注意:比较@Ali Mohammad 的原始方法和 Streams 版本,Streams 版本在我的机器上稍微快一些:

Calculation completed in 1187 milliseconds
Streams calculation completed in 963 milliseconds

比较代码:

startTime = System.currentTimeMillis();
double[][] d = multiplyStreams(a, b);
endTime = System.currentTimeMillis();
System.out.println("Streams calculation completed in " +
        (endTime - startTime) + " milliseconds");

您还可以扩展代码,使其适用于任何 [M x K][K x N] 矩阵乘法。