I. Project Instructions
Overview
Matrix multiplication is a basic mathematical operation that is widely applied in many fields including
scientific computing and pattern recognition. In this project, you will implement a parallel version of matrix
multiplication called pmm.
There are three specific objectives to this project:
• To familiarize yourself with the Linux pthreads library for writing multi-threaded programs.
• To learn how to parallelize a program.
• To learn how to program for performance
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/sysinfo.h>
#define MAX 4000 // max matrix rows/columns
#define THREAD_MAX 100 // max thread number
int matrixA[MAX][MAX] = {0}; //indicate integers 2D array matrixA
int matrixB[MAX][MAX] = {0}; //indicate integers 2D array matrixB
int matrixC[MAX][MAX] = {0}; //indicate integers 2D array matrixC
int n, p, m; // indicate the rows/ columns of matrixA (n, p) matrixB (p, m)
int set[MAX] = {0}; // the thread id
pthread_mutex_t mut; // blocking for the current thread such that those threads wont be collision
typedef struct thread { // struct for thread information
int row_begin; // thread count begin from matrixA row[row_begin]
int row_end; // thread count end
} Thread;
static Thread kids[THREAD_MAX];
void *func(void *arg) // thread function for matrix multiplication
{
int id = *(int *)arg; // thread id
int i, j, k;
for(k = kids[id].row_begin; k < kids[id].row_end; k++)
{
for(i = 0; i < m; i++)
{
for(j = 0; j < p; j++)
{
matrixC[k][i] += matrixA[k][j] * matrixB[j][i];
}
}
}
pthread_exit(NULL); //the thread will be exit when it stored the result
return NULL;
}
void print_matrixC(int nn, int mm) //Print the matrxC
{
int i, j;
for (i = 0; i < nn; ++i) //loop for the row
{
for (j = 0; j < mm; ++j) //loop for the col
{
printf("%d\t", matrixC[i][j]); //print the value in matrixC
}
printf("\n");
}
}
int main(int argc, char *argv[])
{
int i, j; //i,j is a parameter of each iteration
int thread_number =96;
scanf("%d %d %d", &n, &p, &m); //scanf the input
for(i = 0; i < n; i++) //Substitute the input into matrix A
{
for(j = 0; j < p; j++)
{
scanf("%d", &matrixA[i][j]);
}
}
for(i = 0; i < p; i++) //Substitute the input into matrix B
{
for(j = 0; j < m; j++)
{
scanf("%d", &matrixB[i][j]);
}
}
// printf("matrix A \n");
// for (i = 0; i < n; ++i)
// {
// for (j = 0; j < p; ++j)
// {
// printf("%d ", matrixA[i][j]);
// }
// printf("\n");
// }
// printf("matrix B \n");
// for (i = 0; i < p; ++i)
// {
// for (j = 0; j < m; ++j)
// {
// printf("%d ", matrixB[i][j]);
// }
// printf("\n");
// }
// printf("--------------- \n");
int temp = 0; // for store counted rows
for(i = 0; i < thread_number; i++)
{
set[i]=i; // thread id
kids[i].row_begin = temp;
kids[i].row_end = temp + n / thread_number;
temp += n / thread_number;
}
kids[thread_number - 1].row_end = n; // the lastest thread should cout to lastest rows
pthread_t threads[thread_number];
for(i = 0; i < thread_number; i++) //create new threads
{
if(pthread_create(&threads[i], NULL, func, (void *)&set[i]))
{
perror("pthread_created");
}
}
for(i = 0; i < thread_number; i++) // waiting thread work
{
pthread_join(threads[i], NULL);
}
print_matrixC(n, m); //print the matrixC
return 0;
}