Computer Organization and Design assignements
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

126 lignes
3.3 KiB

  1. /*!
  2. \file matmul.c
  3. \brief Matrix multiplication implementation.
  4. \author Nikos Pitsianis
  5. \author Dimitris Floros
  6. \author Christos Choutouridis 8997 <cchoutou@ece.auth.gr>
  7. \date 2020-05-05
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <sys/time.h>
  13. #include <assert.h>
  14. #define MAX_ITER 10
  15. #define sub2ind(i,j,n) (j) + (i)*(n)
  16. /*!
  17. * Square Matrix multiplication
  18. * \param C pointer to output matrix
  19. * \param A pointer to input matrix A
  20. * \param B pointer to input matrix B
  21. * \param n Size of matrices (both sizes)
  22. * \return none
  23. *
  24. * \note
  25. * This version executes row major order ijk
  26. */
  27. void matrixMult(float * const C, float const * const A, float const * const B, int const n) {
  28. for (int i = 0; i < n; i++) { /* rows */
  29. for (int j = 0; j < n; j++) { /* cols */
  30. C[ sub2ind(i,j,n) ] = 0; /* initialize output value */
  31. for (int k = 0; k < n; k++) { /* accumulate products */
  32. C[ sub2ind(i,j,n) ] +=
  33. A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  34. }
  35. }
  36. }
  37. }
  38. /*!
  39. * Initialize matrix with random indices and return the matrix pointer.
  40. *
  41. * \param n The size of the matrix (both of them)
  42. * \return Pointer to allocated and initialized matrix
  43. */
  44. float * matrixInit(int const n) {
  45. float *M = (float *) malloc( n*n*sizeof(float) );
  46. for (int i = 0; i < n; i++) /* rows */
  47. for (int j = 0; j < n; j++) /* cols */
  48. M[ sub2ind(i,j,n) ] = (float)rand()/(float)(RAND_MAX);
  49. return M;
  50. }
  51. int cmpfunc (const void * a, const void * b) {
  52. double v =*(double*)a - *(double*)b;
  53. return (v < 0) ? -1 : (v > 0) ? 1 : 0;
  54. }
  55. /*!
  56. * A unit testing like main function to profile our code
  57. */
  58. int main(int argc, char **argv)
  59. {
  60. struct timeval start, end; /* time structs */
  61. double time[MAX_ITER] = {0.0}; /* execution time array in ms */
  62. float *A, *B, *C; /* matrix declarations */
  63. int n; /* matrix size */
  64. /* read matrix size (or use default) */
  65. if (argc != 2){
  66. fprintf( stderr, "Usage:\n %s n\n where n is the matrix size.\n",
  67. argv[0]);
  68. exit(1);
  69. }
  70. n = atoi( argv[1] );
  71. /* initialize matrices */
  72. A = matrixInit( n );
  73. B = matrixInit( n );
  74. C = (float *) malloc( n*n*sizeof(float) );
  75. /* compute matrix multiplication */
  76. for (int it = 0; it < MAX_ITER; it++) {
  77. gettimeofday(&start, NULL);
  78. matrixMult( C, A, B, n );
  79. gettimeofday(&end, NULL);
  80. time[it] = (end.tv_sec - start.tv_sec) * 1000.0 + /* sec to ms */
  81. (end.tv_usec - start.tv_usec) / 1000.0; /* us to ms */
  82. printf("Iter: %d Time: %f ms\n", it, time[it]);
  83. }
  84. /* we need to use the result -- verify it */
  85. for (int i = 0; i < n; i++) { /* rows */
  86. for (int j = 0; j < n; j++) { /* cols */
  87. float gold = 0;
  88. for (int k = 0; k < n; k++) { /* accumulate products */
  89. gold += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  90. }
  91. assert( (gold - C[sub2ind(i,j,n)]) < 1e-3 );
  92. }
  93. }
  94. // median calculation
  95. qsort ((void*)time, MAX_ITER, sizeof(time[0]), cmpfunc);
  96. printf("Median: %f [msec]\n", (MAX_ITER % 2) ?
  97. time[MAX_ITER/2] :
  98. (time[MAX_ITER/2] + time[MAX_ITER/2 -1]) /2
  99. );
  100. }