diff options
-rw-r--r-- | csci4061/111620_breakout/program.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/csci4061/111620_breakout/program.c b/csci4061/111620_breakout/program.c new file mode 100644 index 0000000..52f67a1 --- /dev/null +++ b/csci4061/111620_breakout/program.c @@ -0,0 +1,155 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <pthread.h> + +#define MATSIZE 5000 + +int mat1[MATSIZE][MATSIZE]; +int mat2[MATSIZE][MATSIZE]; + + +typedef struct argstruct { + int x_start; + int x_end; + int y_start; + int y_end; + int** res_mat; +} args_t; + +int getX_start(int i) { + return (i % 2) * MATSIZE / 2; +} +int getY_start(int i) { + return ((i < 2) ? 0 : 1) * MATSIZE / 2; +} + + +//TODO: Complete this function (to be accessed by a thread) which will +// perform matrix addition on a portion of a matrix, dictated by +// the input parameter 'args' +void * partial_matrix_add(void * args) { + int **dest; + args_t *input = (struct argstruct *) args; // params can be accessed using input pointer + dest = input->res_mat; //can be accessed as dest[][] now + + // Todo: Your code goes here (for reference checkout the pseudo code in the slides) + for (int i=input->x_start; i<input->x_end; i++) { + for (int j=input->y_start; j<input->y_end; j++) { + dest[i][j] = mat1[i][j]*mat2[i][j]; + } + } + return NULL; +} + +int main() { + // to store mulitple dispatcher threads + pthread_t m_threads[4]; + + // to store single default thread + pthread_t s_thread; + + // variable to pass values to multiple thread multiplication + args_t m_args[4]; + + //variable to pass values to single thread muliplication + args_t s_args; + + /** + * initializing matrices for sinlge and multiple matrix multiplication + */ + int i, j, k, c; + struct timeval t_multi_start, t_multi_end, t_single_start, t_single_end; + int ** res_mat_multi = malloc(MATSIZE * sizeof(int *)); + int ** res_mat_single = malloc(MATSIZE * sizeof(int *)); + for(i = 0; i < MATSIZE; i++) { + res_mat_multi[i] = malloc(MATSIZE * sizeof(int)); + res_mat_single[i] = malloc(MATSIZE * sizeof(int)); + } + + //Populate base matrices with random integers + //Initialize result matrices with -1 + for(j = 0; j < MATSIZE; j++) { + for(k = 0; k < MATSIZE; k++) { + mat1[j][k] = rand() % 1000 + 1; + mat2[j][k] = rand() % 1000 + 1; + res_mat_multi[j][k] = -1; + res_mat_single[j][k] = -1; + } + } +//Version 1 ************************************************************************** + //Measure time for multiple thread addition + gettimeofday(&t_multi_start, NULL); + + //Todo: create attribute for detached threads + //Create mulitple threads to populate res_mat_multi with the result + // of performing matrix addition mat1 + mat2 + for(i = 0; i < 4; i++) { + + int x_start = getX_start(i); + int y_start = getY_start(i); + int x_end = x_start + MATSIZE/2; + int y_end = y_start + MATSIZE/2; + m_args[i].res_mat = res_mat_multi; + //your code goes here + //Todo:Create m_agrs using x_start, x_end, y_start, y_end, and create detached threads + m_args[i].x_start = x_start; + m_args[i].x_end = x_end; + m_args[i].y_start = y_start; + m_args[i].y_end = y_end; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&m_threads[i], &attr, partial_matrix_add, (void *) &m_args[i]); + } + + gettimeofday(&t_multi_end, NULL); +//Version 2 ************************************************************************* + + //Measure time for single thread addition + gettimeofday(&t_single_start, NULL); + + // Create single thread to populate res_mat_multi with the result + // of performing matrix addition mat1 + mat2 + + int x_start = 0; + int x_end = MATSIZE; + int y_start = 0; + int y_end = MATSIZE; + s_args.res_mat = res_mat_single; + //your code goes here + //Todo: Assign values to s_args using x_start, y_start etc. + s_args.x_start = x_start; + s_args.y_start = y_start; + s_args.x_end = x_end; + s_args.y_end = y_end; + //Todo:Create thread + pthread_create(&s_thread, NULL, partial_matrix_add, (void *) &s_args); + //Todo:join thread + pthread_join(s_thread, NULL); + gettimeofday(&t_single_end, NULL); + +// ********************************************************************************** + //Don't change anything from here + //Test to ensure that both methods produce the same result + c = 0; + for(j = 0; j < MATSIZE; j++) { + for(k = 0; k < MATSIZE; k++) { + if(res_mat_multi[j][k] == res_mat_single[j][k] && res_mat_multi[j][k] != -1) { + c++; + } + } + } + printf("Verification: %d out of %d entries matched.\n", c, MATSIZE * MATSIZE); + //Display time for each version + double time_taken; + time_taken = (t_multi_end.tv_sec - t_multi_start.tv_sec) * 1e6; + time_taken = (time_taken + (t_multi_end.tv_usec - t_multi_start.tv_usec)) * 1e-6; + printf("Time for multiple threads: %f seconds\n", time_taken); + + time_taken = (t_single_end.tv_sec - t_single_start.tv_sec) * 1e6; + time_taken = (time_taken + (t_single_end.tv_usec - t_single_start.tv_usec)) * 1e-6; + printf("Time for single thread: %f seconds\n", time_taken); + return 0; +} |