aboutsummaryrefslogtreecommitdiffstats
path: root/csci4061/111620_breakout/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'csci4061/111620_breakout/program.c')
-rw-r--r--csci4061/111620_breakout/program.c155
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;
+}