Skip to content

Instantly share code, notes, and snippets.

@chintanparikh
Created April 28, 2014 22:51
Show Gist options
  • Save chintanparikh/11386380 to your computer and use it in GitHub Desktop.
Save chintanparikh/11386380 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
typedef struct _Matrix {
int rows;
int cols;
int** elements;
} Matrix;
typedef struct _thread_multiply_params {
int *row_vector, *col_vector, i, j, length;
Matrix* result;
pthread_t thread_id;
} thread_multiply_params;
Matrix* create_matrix(int rows, int cols)
{
Matrix* matrix = malloc(sizeof(Matrix));
matrix->elements = malloc(sizeof(int*) * rows);
int i;
for (i = 0; i < rows; i++)
{
matrix->elements[i] = calloc(cols, sizeof(int));
}
matrix->rows = rows;
matrix->cols = cols;
return matrix;
}
void print_matrix(Matrix* matrix)
{
int i, j;
for (i = 0; i < matrix->rows; i++)
{
for (j = 0; j < matrix->cols; j++)
{
printf("%d ", matrix->elements[i][j]);
}
printf("\n");
}
}
Matrix* create_matrix_with_data(int rows, int cols)
{
Matrix* matrix = create_matrix(rows, cols);
int i, j, count = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
matrix->elements[i][j] = rand() % 300;
count++;
}
}
return matrix;
}
static void* threaded_multiply(void* params)
{
thread_multiply_params *multiply_params = params;
int i, sum = 0;
for (i = 0; i < multiply_params->length; i++)
{
// printf("%d x %d\n", multiply_params->row_vector[i], multiply_params->col_vector[i]);
sum += multiply_params->row_vector[i] * multiply_params->col_vector[i];
}
multiply_params->result->elements[multiply_params->i][multiply_params->j] = sum;
return NULL;
}
int* row_vector(Matrix* matrix, int row)
{
return matrix->elements[row];
}
int* column_vector(Matrix* matrix, int col)
{
int *vector, i;
vector = malloc(sizeof(int) * matrix->rows);
for (i = 0; i < matrix->rows; i++)
{
// printf("%d - %d\n", i, matrix->elements[i][col]);
vector[i] = matrix->elements[i][col];
}
return vector;
}
Matrix* multiply(Matrix* matrix1, Matrix* matrix2)
{
Matrix* result = create_matrix(matrix1->rows, matrix2->cols);
// print_matrix(result);
int i, j;
/*
* Output will be of size matrix1.rows x matrix2.cols
*
* Create the new matrix
* for i < num rows
* for j < num cols
* threaded_multiply(row[i], col[j], i, j, answer_matrix)
*/
thread_multiply_params **params = malloc(sizeof(thread_multiply_params*) * matrix1->rows);
for (i = 0; i < matrix1->rows; i++)
{
params[i] = malloc(sizeof(thread_multiply_params) * matrix2->cols);
}
for (i = 0; i < matrix1->rows; i++)
{
for (j = 0; j < matrix2->cols; j++)
{
params[i][j].row_vector = row_vector(matrix1, i);
params[i][j].col_vector = column_vector(matrix2, j);
params[i][j].i = i;
params[i][j].j = j;
params[i][j].result = result;
// * Note that length can be either matrix1->rows or matrix2->cols, they must be equal
params[i][j].length = matrix2->cols;
pthread_create(&(params[i][j].thread_id), NULL, &threaded_multiply, &params[i][j]);
}
}
for (i = 0; i < matrix1->rows; i++)
{
for (j = 0; j < matrix2->cols; j++)
{
pthread_join(params[i][j].thread_id, NULL);
}
}
return result;
}
Matrix* non_threaded_multiply(Matrix* matrix1, Matrix* matrix2)
{
Matrix* result = create_matrix(matrix1->rows, matrix2->cols);
int i, j, k;
for (i = 0; i < matrix1->rows; i++)
{
for (j = 0; j < matrix2->cols; j++)
{
for (k = 0; k < matrix1->cols; k++)
{
result->elements[i][j] += matrix1->elements[i][k] * matrix2->elements[k][j];
}
}
}
return result;
}
int main(int argc, char* argv[])
{
int a = 100, b = 100;
printf("Creating first matrix\n");
Matrix *matrix1 = create_matrix_with_data(a, b);
printf("Creating second matrix\n");
Matrix *matrix2 = create_matrix_with_data(b, a);
printf("Done creating matrices\n");
int msec;
clock_t start, diff;
start = clock();
printf("Starting multiply\n");
Matrix* result = multiply(matrix1, matrix2);
diff = clock() - start;
msec = diff * 1000 / CLOCKS_PER_SEC;
printf("Time taken for threaded is %d seconds %d milliseconds\n", msec/1000, msec%1000);
// print_matrix(result);
start = clock();
Matrix* slower_result = non_threaded_multiply(matrix1, matrix2);
diff = clock() - start;
msec = diff * 1000 / CLOCKS_PER_SEC;
printf("Time taken for non threaded is %d seconds %d milliseconds\n", msec/1000, msec%1000);
// print_matrix(slower_result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment