/******************************************************** * matrix_threads.c * * A master thread spawns separate child threads to compute each * ROW in the resulting array. Each of the child threads is passed * a pointer to a structure that contains the element indices and * pointers to starting and resulting arrays. * * The master thread joins to each thread, prints out the result and * exits. * * COMPILE Using: * gcc -lpthread -pg -Wall -Werror matrix_threads_gprof.c -o matrix_threads_gprof.out * or for Bebugging use * gcc -DDEBUG -lpthread -Werror -Wall matrix_threads.c -o matrix_threads * RUN Using * ./matrix_threads_gprof.out * Elapsed Time:~ 3.90 Sec. * GPROF Using: * gprof ./matrix_threads_gprof.out * To create a visual Call Graph: * gprof ./matrix_threads.out | python gprof2dot.py | dot -Tpng -o output.png */ #include #include #include #include "support.h" #include #include #ifdef DEBUG #define ARRAY_SIZE 10 #else #define ARRAY_SIZE 1000 #endif struct itimerval itimer; typedef int matrix_t[ARRAY_SIZE][ARRAY_SIZE]; typedef struct { int id; int size; int Arow; int Bcol; matrix_t *MA, *MB, *MC; } package_t; matrix_t MA,MB,MC; void printMatrix(int size, matrix_t M){ int row, column; for(row = 0; row < size; row ++) { for (column = 0; column < size; column++) { printf("%5d ",M[row][column]); } printf("\n"); } } /* Fill in matrices A and B with Values */ void initMatrices(int size, matrix_t MA, matrix_t MB) { int row, column; for (row = 0; row < size; row++) { for (column = 0; column < size; column++) { MA[row][column] = 1; } } for (row = 0; row < size; row++) { for (column = 0; column < size; column++) { MB[row][column] = row + column + 1; } } printf("MATRIX A is ready:\n"); #ifdef DEBUG printMatrix(size, MA); #endif printf("MATRIX B is ready:\n"); #ifdef DEBUG printMatrix(size, MB); #endif } /* * Routine to multiply a row by a column and place element in * resulting matrix. */ void mult(int size, int row, matrix_t MA, matrix_t MB, matrix_t MC) { int position, column; for (column = 0; column < size; column++){ MC[row][column] = 0; for(position = 0; position < size; position++) { MC[row][column] += ( MA[row][position] * MB[position][column] ) ; } } } /* * Routine to start off a worker thread. */ void *mult_worker(void *arg) { package_t *p=(package_t *)arg; #ifdef DEBUG printf("MATRIX THREAD %d: processing A row %d, B col %d\n", p->id, p->Arow, p->Bcol ); #endif /* Set the profile timer value */ /*getitimer(ITIMER_PROF, &itimer);*/ mult(p->size, p->Arow, *(p->MA), *(p->MB), *(p->MC)); #ifdef DEBUG printf("MATRIX THREAD %d: complete\n", p->id); #endif free(p); return(NULL); } /* * Main(): allocates matrix, assigns values, then * creates threads to process rows and columns. */ extern int main(int argc, char **argv) { int size, row, column, num_threads, i; pthread_t *threads; /* threads holds the thread ids of all threads created, so that the main thread can join with them. */ package_t *p; /* argument list to pass to each thread. */ /* Currently size hardwired to ARRAY_SIZE size */ size = ARRAY_SIZE; /*setitimer(ITIMER_PROF, &itimer, NULL); */ /* one thread will be created for each element of the matrix. */ threads = (pthread_t *)malloc(size*size*sizeof(pthread_t)); /* Initialize the matrices A and B. */ initMatrices(size, MA, MB); startTime(); /* Process Matrix, by row, column, Create a thread to process each element in the resulting matrix*/ num_threads = 0; for(row = 0; row < size; row++) { // for (column = 0; column < size; column++) { column = 0; p = (package_t *)malloc(sizeof(package_t)); p->id = num_threads; p->size = size; p->Arow = row; p->Bcol = column; (p->MA) = &MA; (p->MB) = &MB; (p->MC) = &MC; pthread_create(&threads[num_threads], NULL, mult_worker, (void *) p); #ifdef DEBUG printf("MATRIX MAIN THREAD: thread %d created\n", num_threads); #endif num_threads++; // } } /* Synchronize on the completion of the element in each thread. */ for (i = 0; i < (size); i++) { pthread_join(threads[i], NULL); #ifdef DEBUG printf("MATRIX MAIN THREAD: child %d has joined\n", i); #endif } stopTime(); elapsedTime(); /* Print results */ #ifdef DEBUG printf("MATRIX: The resulting matrix C is;\n"); printMatrix(size, MC); #endif return 0; }