Multiplication of Matrix using threads

Multiplication of matrix does take time surely. Time complexity of matrix multiplication is O(n^3) using normal matrix multiplication. And Strassen algorithm improves it and its time complexity is O(n^(2.8074)).

But, Is there any way to improve the performance of matrix multiplication using the normal method.
Multi-threading can be done to improve it. In multi-threading, instead of utilizing a single core of your processor, we utilizes all or more core to solve the problem.

We create different threads, each thread evaluating some part of matrix multiplication.
Depending upon the number of cores your processor has, you can create the number of threads required. Although you can create as many threads as you need, a better way is to create each thread for one core.



In second approach,we create a seperate thread for each element in resultant matrix. Using pthread_exit() we return computed value from each thread which is collected by pthread_join(). This approach does not make use of any global variables.

Examples:

Input : 
Matrix A
 1 0 0
 0 1 0
 0 0 1

Matrix B
 2 3 2
 4 5 1
 7 8 6

Output : Multiplication of A and B
2 3 2
4 5 1
7 8 6

NOTE* It is advised to execute the program in linux based system
Compile in linux using following code:

g++ -pthread program_name.cpp
filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP Program to multiply two matrix using pthreads
#include <bits/stdc++.h>
using namespace std;
  
// maximum size of matrix
#define MAX 4
  
// maximum number of threads
#define MAX_THREAD 4
  
int matA[MAX][MAX];
int matB[MAX][MAX];
int matC[MAX][MAX];
int step_i = 0;
  
void* multi(void* arg)
{
    int core = step_i++;
  
    // Each thread computes 1/4th of matrix multiplication
    for (int i = core * MAX / 4; i < (core + 1) * MAX / 4; i++) 
        for (int j = 0; j < MAX; j++) 
            for (int k = 0; k < MAX; k++) 
                matC[i][j] += matA[i][k] * matB[k][j];
}
  
// Driver Code
int main()
{
    // Generating random values in matA and matB
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) {
            matA[i][j] = rand() % 10;
            matB[i][j] = rand() % 10;
        }
    }
  
    // Displaying matA
    cout << endl
         << "Matrix A" << endl;
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) 
            cout << matA[i][j] << " ";
        cout << endl;
    }
  
    // Displaying matB
    cout << endl
         << "Matrix B" << endl;
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) 
            cout << matB[i][j] << " ";        
        cout << endl;
    }
  
    // declaring four threads
    pthread_t threads[MAX_THREAD];
  
    // Creating four threads, each evaluating its own part
    for (int i = 0; i < MAX_THREAD; i++) {
        int* p;
        pthread_create(&threads[i], NULL, multi, (void*)(p));
    }
  
    // joining and waiting for all threads to complete
    for (int i = 0; i < MAX_THREAD; i++) 
        pthread_join(threads[i], NULL);    
  
    // Displaying the result matrix
    cout << endl
         << "Multiplication of A and B" << endl;
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) 
            cout << matC[i][j] << " ";        
        cout << endl;
    }
    return 0;
}

chevron_right


Output:

Matrix A
3 7 3 6 
9 2 0 3 
0 2 1 7 
2 2 7 9 

Matrix B
6 5 5 2 
1 7 9 6 
6 6 8 9 
0 3 5 2 

Multiplication of A and B
43 100 132 87 
56 68 78 36 
8 41 61 35 
56 93 129 97 

An approach without using global variables:

NOTE* It is advised to execute the program in linux based system
Compile in linux using following code:

g++ -pthread program_name.cpp
filter_none

edit
close

play_arrow

link
brightness_4
code

// C Program to multiply two matrix using pthreads without 
// use of global variables 
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
#define MAX 4
  
  
//Each thread computes single element in the resultant matrix
void *mult(void* arg)
{
    int *data = (int *)arg;
    int k = 0, i = 0;
      
    int x = data[0];
    for (i = 1; i <= x; i++)
           k += data[i]*data[i+x];
      
    int *p = (int*)malloc(sizeof(int));
         *p = k;
      
//Used to terminate a thread and the return value is passed as a pointer
    pthread_exit(p);
}
  
//Driver code
int main()
{
  
    int matA[MAX][MAX]; 
    int matB[MAX][MAX]; 
      
      
    int r1=MAX,c1=MAX,r2=MAX,c2=MAX,i,j,k;
  
  
    // Generating random values in matA
    for (i = 0; i < r1; i++) 
            for (j = 0; j < c1; j++) 
                   matA[i][j] = rand() % 10; 
            
        // Generating random values in matB 
    for (i = 0; i < r1; i++) 
            for (j = 0; j < c1; j++) 
                   matB[i][j] = rand() % 10; 
     
    // Displaying matA         
    for (i = 0; i < r1; i++){
        for(j = 0; j < c1; j++)
            printf("%d ",matA[i][j]);
        printf("\n");
    }
              
    // Displaying matB                
    for (i = 0; i < r2; i++){
        for(j = 0; j < c2; j++)
            printf("%d ",matB[i][j]);
        printf("\n");    
    }
      
      
    int max = r1*c2;
      
      
    //declaring array of threads of size r1*c2        
    pthread_t *threads;
    threads = (pthread_t*)malloc(max*sizeof(pthread_t));
      
    int count = 0;
    int* data = NULL;
    for (i = 0; i < r1; i++)
        for (j = 0; j < c2; j++)
               {
                 
               //storing row and column elements in data 
            data = (int *)malloc((20)*sizeof(int));
            data[0] = c1;
      
            for (k = 0; k < c1; k++)
                data[k+1] = matA[i][k];
      
            for (k = 0; k < r2; k++)
                data[k+c1+1] = matB[k][j];
               
             //creating threads
                pthread_create(&threads[count++], NULL, 
                               mult, (void*)(data));
                  
                    }
      
    printf("RESULTANT MATRIX IS :- \n");
    for (i = 0; i < max; i++) 
    {
      void *k;
        
      //Joining all threads and collecting return value 
      pthread_join(threads[i], &k);
             
            
          int *p = (int *)k;
      printf("%d ",*p);
      if ((i + 1) % c2 == 0)
          printf("\n");
    }
  
      
  
  return 0;
}

chevron_right


Output:

Matrix A
3 7 3 6 
9 2 0 3 
0 2 1 7 
2 2 7 9

Matrix B
6 5 5 2 
1 7 9 6 
6 6 8 9 
0 3 5 2 

Multiplication of A and B
43 100 132 87 
56 68 78 36 
8 41 61 35 
56 93 129 97 



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : GauravKshirsagar1



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.