Skip to content

Instantly share code, notes, and snippets.

@sergiocampama
Created March 12, 2012 02:00
Show Gist options
  • Save sergiocampama/2019262 to your computer and use it in GitHub Desktop.
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.
//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;
}
@sergiocampama
Copy link
Author

Compile with gcc benchmark.c -o benchmark and run with ./benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment