I have been tasked to calculate the time it takes for my PC to do a matrix multiplication with dimensions 2048x2048 (and get 10 samples) and I was given the following function
/*
* 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'
and this to use in my main
double time = 0.0;
/* 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 */
fprintf("Iter: %d Time: %f\n", it, time);
}
So what I have to do is initialize the arrays A and B with random values?
I can't think of a way.
This is what I have so far
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#define sub2ind(i,j,n) (j) (i)*(n)
float *const A, *const B, *const C;
void matrixMult(float *const C, /* output matrix */
float const *const A, /* first matrix */
float const *const B, /* second matrix */
int const n);
int main() {
int n = 2048;
double time = 0.0;
struct timeval start, end;
/* compute matrix multiplication */
for (int it = 0; it < 10; 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 */
fprintf("Iter: %d Time: %f\n", it 1, time);
}
return 0;
}
/*
* 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'
CodePudding user response:
float *const A, *const B, *const C;
are global pointers. Each, at program start, are given a value 0, a null pointer. Since they are const
, the pointer cannot change. We are stuck.
Instead, do not make them const
- there is no need for that. In main()
, allocate memory and values before the test.
Note that matrixMult()
uses a pointer to float
rather than a more 2D like type. We can take advantage of that when first assigning A, B
.
float *A, *B, *C;
int main() {
...
A = malloc(sizeof A[0] * n * n);
B = malloc(sizeof B[0] * n * n);
// Zero fill product array in case multiplication is in error.
// Assigning simplifies debugging.
C = calloc((size_t)n * n, sizeof C[0]);
// If out-of-memory ...
if (A == NULL || B == NULL || C == NULL) {
// Might as well exit code here with an error message
}
// Fill A[], B[] with something interesting.
for (size_t i = 0; i < (size_t)n * n; i)) {
A[i] = rand();
B[i] = rand();
}
// Test code here.
...
// Clean up
free(A); A = NULL;
free(B); B = NULL;
free(C); C = NULL;
}
Notes: #define sub2ind(i,j,n) (j) (i)*(n)
risks precedence issues. Better as #define sub2ind(i,j,n) ((j) (i)*(n))
. Even better as #define sub2ind(i,j,n) (j) (size_t)(i)*(n)
to insure size_t
math as int
math is more likely will to overflow.
CodePudding user response:
I would reccoment for you to check out the standard function rand()
int rand( void )
It returns with a random intiger between 0 to RAND_MAX.