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