Ali mohammad
Ali mohammad

Reputation: 33

Using ThreadPool for parallelisation of Matrix Multiplication

I am trying to parallel a matrix multiplication.

I have achieved parallelization by calculating each cell of Matrix C in a separate thread. (I hope i have done this correctly).

My question here is if using thread pool is the best way for creating threads. (Sorry i am unfamiliar with this and someone suggested to do in this way)

Also will i see a great difference in the time it takes to calculate with a sequential version of the program compared to this?

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];
        }
    }
}

Upvotes: 1

Views: 1345

Answers (1)

Durandal
Durandal

Reputation: 20059

You have to balance between scheduling overhead, operation duration and number of available cores. For a start, size your thread pool according to the number of cores available newFixedThreadPool(Runtime.getRuntime().availableProcessors()).

To minimize scheduling overhead you want to slice the operation into just as many independent tasks (of ideally equal execution time) as you have processors.

Generally, the smaller the operation you do in a slice, the more scheduling overhead you have. What you have now (N square tasks) has excessive overhead (you will create and submit 2000 times 2000 Multi runnables which each do very little work).

Upvotes: 2

Related Questions