Created
April 28, 2014 22:51
-
-
Save chintanparikh/11386380 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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, ¶ms[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