Implement a multithreaded version of matrix multiplication. The normal method for multiplying two such matrices involves performing all the calculations in the main thread. Each element (i,j) of the product matrix is obtained by multiplying the ith row of the first matrix with the jth column of the second. In the multi-threaded version, you will divide this computation among threads to achieve parallelism. Initialize two 3X3 matrices with random values. Create 3 threads. Each thread will compute 1/3rd of the product matrix. So the first thread calculates the product elements for the first row, the second for the next row and so on. The main thread should wait for all the threads to complete, and then print the resultant product matrix. Verify that this produces the same result as the normal method.
Solution:
import java.util.Random; public class MatrixMultiplication { //Creating the matrix static int[][] mat = new int[3][3]; static int[][] mat2 = new int[3][3]; static int[][] result = new int[3][3]; public static void main(String [] args){ //Creating the object of random class Random rand = new Random(); //Filling first matrix with random values for (int i = 0; i < mat.length; i++) { for (int j = 0; j < mat[i].length; j++) { mat[i][j]=rand.nextInt(10); } } //Filling second matrix with random values for (int i = 0; i < mat2.length; i++) { for (int j = 0; j < mat2[i].length; j++) { mat2[i][j]=rand.nextInt(10); } } //Printing the first matrix System.out.println("This is first matrix:"); for (int i = 0; i < mat.length; i++) { for (int j = 0; j < mat[i].length; j++) { System.out.print(mat[i][j]+" "); } System.out.println(); } //Printing the second matrix System.out.println("\nThis is second matrix:"); for (int i = 0; i < mat.length; i++) { for (int j = 0; j < mat[i].length; j++) { System.out.print(mat2[i][j]+" "); } System.out.println(); } try{ //Object of multiply Class Multiply multiply = new Multiply(3,3); //Threads MatrixMultiplier thread1 = new MatrixMultiplier(multiply); MatrixMultiplier thread2 = new MatrixMultiplier(multiply); MatrixMultiplier thread3 = new MatrixMultiplier(multiply); //Implementing threads Thread th1 = new Thread(thread1); Thread th2 = new Thread(thread2); Thread th3 = new Thread(thread3); //Starting threads th1.start(); th2.start(); th3.start(); th1.join(); th2.join(); th3.join(); }catch (Exception e) { e.printStackTrace(); } //Printing the result System.out.println("\n\nResult:"); for (int i = 0; i < result.length; i++) { for (int j = 0; j < result[i].length; j++) { System.out.print(result[i][j]+" "); } System.out.println(); } }//End main }//End Class
//Multiply Class class Multiply extends MatrixMultiplication { private int i; private int j; private int chance; public Multiply(int i, int j){ this.i=i; this.j=j; chance=0; } //Matrix Multiplication Function public synchronized void multiplyMatrix(){ int sum=0; int a=0; for(a=0;a<i;a++){ sum=0; for(int b=0;b<j;b++){ sum=sum+mat[chance][b]*mat2[b][a]; } result[chance][a]=sum; } if(chance>=i) return; chance++; } }//End multiply class
//Thread Class class MatrixMultiplier implements Runnable { private final Multiply mul; public MatrixMultiplier(Multiply mul){ this.mul=mul; } @Override public void run() { mul.multiplyMatrix(); } }
I have applied this code. I tried it multiplying 1000x1000 length two matrices. Results are surprising: If I use 1 thread it takes ~80 ms and if I use 2 threads it takes ~100 ms. I did not stop, I tried 4 threads and guess what? It takes ~166 ms. What do you think about this situation?
ReplyDelete