diff --git a/Q6-cache/Makefile b/Q6-cache/Makefile new file mode 100644 index 0000000..54d8fc1 --- /dev/null +++ b/Q6-cache/Makefile @@ -0,0 +1,32 @@ +SHELL := /bin/bash + +###################################################################### +### EXECUTABLES + +CC = gcc +FLAGS = -O3 -Wall -std=gnu99 +RM = rm -rf +LINK = -lm + +###################################################################### +### TARGET FILES + +MAIN = matmul + +###################################################################### +### CLEAN-UP FILES + +FILES_CLEAN = $(MAIN) *~ + +###################################################################### +### COMMANDS -- ! DO NOT CHANGE BELOW ! + +all: $(MAIN) + +$(MAIN): $(MAIN).c + $(CC) $(FLAGS) $(DEFS) $^ -o $@ $(LINK) + +clean: + $(RM) $(FILES_CLEAN) *.o *~ + +.PHONY: $(MAIN) diff --git a/Q6-cache/matmul.c b/Q6-cache/matmul.c new file mode 100644 index 0000000..38685cd --- /dev/null +++ b/Q6-cache/matmul.c @@ -0,0 +1,110 @@ +/*! + \file matmul.c + \brief Matrix multiplication implementation. + + \author Nikos Pitsianis + \author Dimitris Floros + \date 2020-05-05 +*/ + + +#include +#include +#include +#include +#include + +#define MAX_ITER 10 +#define sub2ind(i,j,n) (j) + (i)*(n) + +/* + * matrixMult - Matrix multiplication + */ +void matrixMult(float * const C, /* output matrix */ + float const * const A, /* first matrix */ + float const * const B, /* second matrix */ + int const n) { /* number of rows/cols */ + + for (int i = 0; i < n; i++) { /* rows */ + for (int j = 0; j < n; j++) { /* cols */ + + /* initialize output value */ + C[ sub2ind(i,j,n) ] = 0; + + for (int k = 0; k < n; k++) { /* accumulate products */ + C[ sub2ind(i,j,n) ] += + A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ]; + } + + } + } + +} // end function 'matrixMult' + +/* + * matrixInitAdd: + * Initialize matrix with random indices and return the matrix + * pointer. + * + */ +float * matrixInit(int const n) { + + float *M = (float *) malloc( n*n*sizeof(float) ); + + for (int i = 0; i < n; i++) /* rows */ + for (int j = 0; j < n; j++) /* cols */ + M[ sub2ind(i,j,n) ] = (float)rand()/(float)(RAND_MAX); + + return M; + +} // end function 'matrixInitAdd' + +int main(int argc, char **argv) +{ + + struct timeval start, end; /* time structs */ + double time = 0.0; /* execution time in ms */ + float *A, *B, *C; /* matrix declarations */ + int n; /* matrix size */ + + /* read matrix size (or use default) */ + if (argc != 2){ + fprintf( stderr, "Uasge:\n %s n\n where n is the matrix size.\n", + argv[0]); + exit(1); + } + n = atoi( argv[1] ); + + /* initialize matrices */ + A = matrixInit( n ); + B = matrixInit( n ); + C = (float *) malloc( n*n*sizeof(float) ); + + /* compute matrix multiplication */ + for (int it = 0; it < MAX_ITER; it++) { + gettimeofday(&start, NULL); + matrixMult( C, A, B, n ); + gettimeofday(&end, NULL); + + time = ( (end.tv_sec - start.tv_sec) * 1000.0 + /* sec to ms */ + (end.tv_usec - start.tv_usec) / 1000.0 ); /* us to ms */ + + printf("Iter: %d Time: %f ms\n", it, time); + } + + /* we noeed to use the result -- verify it */ + for (int i = 0; i < n; i++) { /* rows */ + for (int j = 0; j < n; j++) { /* cols */ + + float gold = 0; + + for (int k = 0; k < n; k++) { /* accumulate products */ + gold += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ]; + } + + assert( (gold - C[sub2ind(i,j,n)]) < 1e-3 ); + + } + } +} +