Created
March 12, 2012 02:00
-
-
Save sergiocampama/2019262 to your computer and use it in GitHub Desktop.
Benchmark for measuring a computer performance written in C. Based in matrix inversion algorithms from 'Recipes in C', with number of retries and matrix size configurables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Sergio Campamá 11-3-2012 | |
//sergiocampama@gmail.com | |
//Numerical functions taken from the book 'Recipes in C' | |
#include <math.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <time.h> | |
#include <string.h> | |
#define NR_END 1 | |
#define FREE_ARG char* | |
#define TINY 1.0e-20 | |
double *vector(long nl, long nh) | |
{ | |
double *v; | |
v = (double *) malloc((size_t) ((nh - nl + 1 + NR_END) * sizeof(double))); | |
if (!v) | |
{ | |
printf("Allocation failure in vector()"); | |
exit(1); | |
} | |
return v - nl + NR_END; | |
} | |
int *ivector(long nl, long nh) | |
{ | |
int *v; | |
v = (int *) malloc((size_t) ((nh - nl + 1 + NR_END) * sizeof(int))); | |
if (!v) | |
{ | |
printf("Allocation failure in ivector()"); | |
exit(1); | |
} | |
return v - nl + NR_END; | |
} | |
void free_ivector(int *v, long nl, long nh) | |
{ | |
free((FREE_ARG) (v + nl - NR_END)); | |
} | |
void free_vector(double *v, long nl, long nh) | |
{ | |
free((FREE_ARG) (v + nl - NR_END)); | |
} | |
double **matrix(long nrl, long nrh, long ncl, long nch) | |
{ | |
long i, nrow = nrh - nrl + 1, ncol = nch - ncl + 1; | |
double **m; | |
m = (double **) malloc((size_t)((nrow + NR_END) * sizeof(double*))); | |
if (!m) | |
{ | |
printf("Allocation failure 1 in matrix()"); | |
exit(1); | |
} | |
m += NR_END; | |
m -= nrl; | |
m[nrl] = (double *) malloc((size_t)((nrow * ncol + NR_END) * sizeof(double))); | |
if (!m[nrl]) | |
{ | |
printf("Allocation failure 2 in matrix()"); | |
exit(1); | |
} | |
m[nrl] += NR_END; | |
m[nrl] -= ncl; | |
for(i = nrl + 1; i <= nrh; i++) m[i] = m[i - 1] + ncol; | |
return m; | |
} | |
void free_matrix(double **m, long nrl, long nrh, long ncl, long nch) | |
{ | |
free((FREE_ARG) (m[nrl] + ncl - NR_END)); | |
free((FREE_ARG) (m + nrl - NR_END)); | |
} | |
void ludcmp(double **a, int n, int *indx, double *d) | |
{ | |
int i, imax, j, k; | |
double big, dum, sum, temp; | |
double *vv; | |
vv = vector(1, n); | |
*d = 1.0; | |
for (i = 1; i <= n; i++) { | |
big = 0.0; | |
for (j = 1; j <= n; j++) | |
if ((temp = fabs(a[i][j])) > big) | |
big = temp; | |
if (big == 0.0) | |
printf("Singular matrix in routine ludcmp"); | |
vv[i] = 1.0 / big; | |
} | |
for (j = 1; j <= n; j++) { | |
for (i = 1; i < j; i++) { | |
sum = a[i][j]; | |
for (k = 1; k < i; k++) | |
sum -= a[i][k] * a[k][j]; | |
a[i][j] = sum; | |
} | |
big = 0.0; | |
for (i = j; i <= n; i++) { | |
sum = a[i][j]; | |
for (k = 1; k < j; k++) | |
sum -= a[i][k] * a[k][j]; | |
a[i][j] = sum; | |
if ((dum = vv[i] * fabs(sum)) >= big) { | |
big = dum; | |
imax = i; | |
} | |
} | |
if (j != imax) { | |
for (k = 1; k <= n; k++) { | |
dum = a[imax][k]; | |
a[imax][k] = a[j][k]; | |
a[j][k] = dum; | |
} | |
*d = -(*d); | |
vv[imax] = vv[j]; | |
} | |
indx[j] = imax; | |
if (a[j][j] == 0.0) | |
a[j][j] = TINY; | |
if (j != n) { | |
dum = 1.0 / (a[j][j]); | |
for (i = j + 1; i <= n; i++) | |
a[i][j] *= dum; | |
} | |
} | |
free_vector(vv, 1, n); | |
} | |
void lubksb(double **a, int n, int *indx, double b[]) | |
{ | |
int i, ii = 0, ip, j; | |
double sum; | |
for (i = 1; i <= n; i++) { | |
ip = indx[i]; | |
sum = b[ip]; | |
b[ip] = b[i]; | |
if (ii) | |
for (j = ii; j <= i - 1; j++) sum -= a[i][j] * b[j]; | |
else if (sum) ii = i; | |
b[i] = sum; | |
} | |
for (i = n; i >= 1; i--) { | |
sum = b[i]; | |
for (j = i + 1; j <= n; j++) sum -= a[i][j] * b[j]; | |
b[i] = sum / a[i][i]; | |
} | |
} | |
void terminate(char *message) | |
{ | |
printf("%s\n", message); | |
exit(1); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
double **a, **y, d, *col; | |
int i, j, *indx, n, retries; | |
n = 100; | |
retries = 20; | |
if (argc > 1) | |
{ | |
i = 1; | |
while(i < argc) | |
{ | |
if(strcmp(argv[i], "-r") == 0) | |
{ | |
if(i == argc - 1) | |
terminate("You must provide a positive integer after -r"); | |
retries = atoi(argv[++i]); | |
if(retries <= 0) | |
terminate("r must be greater than 0"); | |
} | |
else if(strcmp(argv[i], "-m") == 0) | |
{ | |
if(i == argc - 1) | |
terminate("You must provide a positive integer after -m"); | |
n = atoi(argv[++i]); | |
if(n <= 0) | |
terminate("m must be greater than 0"); | |
} | |
else | |
{ | |
terminate("Valid options are -r X and -m X, where X is a positive integer."); | |
return 1; | |
} | |
i++; | |
} | |
} | |
printf("Initiating with m = %d and r = %d\n", n, retries); | |
clock_t start, end; | |
double elapsed; | |
start = clock(); | |
while(retries-- && retries > 0) | |
{ | |
indx = ivector(1, n); | |
a = matrix(1, n, 1, n); | |
y = matrix(1, n, 1, n); | |
col = vector(1, n); | |
for(j = 1; j <= n; j++) | |
{ | |
for (i = 1; i <= n; i++) | |
{ | |
a[i][j] = 50.0 * i - 23 * j; | |
y[i][j] = 0.0; | |
} | |
} | |
ludcmp(a, n, indx, &d); | |
for(j = 1; j <= n; j++){ | |
for (i = 1; i <= n; i++) col[i] = 0.0; | |
col[j] = 1.0; | |
lubksb(a, n, indx, col); | |
for (i = 1; i <= n; i++) | |
y[i][j] = col[i]; | |
} | |
free_ivector(indx, 1, n); | |
free_vector(col, 1, n); | |
free_matrix(a, 1, n, 1, n); | |
free_matrix(y, 1, n, 1, n); | |
} | |
end = clock(); | |
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; | |
printf("Benchmark took %f seconds\n", elapsed); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compile with
gcc benchmark.c -o benchmark
and run with./benchmark
.