summaryrefslogtreecommitdiff
path: root/cleanbench.c
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2008-11-14 04:56:19 +0000
committerMatt Turner <mattst88@gmail.com>2008-11-14 04:56:19 +0000
commitfdb0f96aa0254eb5864d34fb3ae734e178935a3f (patch)
tree14e73a2b856f9d9771e4dca1dcb8b11083e1fb88 /cleanbench.c
parentf067d71ef7e5bc4e670641b0499f82384f95b764 (diff)
-- Rename nbench0.{c,h} to cleanbench.{c,h}
-- Makefile now generates cleanbench git-svn-id: svn://mattst88.com/svn/cleanbench/trunk@32 0d43b9a7-5ab2-4d7b-af9d-f64450cef757
Diffstat (limited to 'cleanbench.c')
-rw-r--r--cleanbench.c872
1 files changed, 872 insertions, 0 deletions
diff --git a/cleanbench.c b/cleanbench.c
new file mode 100644
index 0000000..7b8e118
--- /dev/null
+++ b/cleanbench.c
@@ -0,0 +1,872 @@
+
+/*
+** cleanbench.c
+*/
+
+/*******************************************
+** BYTEmark (tm) **
+** BYTE MAGAZINE'S NATIVE MODE BENCHMARKS **
+** FOR CPU/FPU **
+** ver 2.0 **
+** Rick Grehan, BYTE Magazine **
+********************************************
+** NOTE: These benchmarks do NOT check for the presence
+** of an FPU. You have to find that out manually.
+**
+** REVISION HISTORY FOR BENCHMARKS
+** 9/94 -- First beta. --RG
+** 12/94 -- Bug discovered in some of the integer routines
+** (IDEA, Huffman,...). Routines were not accurately counting
+** the number of loops. Fixed. --RG (Thanks to Steve A.)
+** 12/94 -- Added routines to calculate and display index
+** values. Indexes based on DELL XPS 90 (90 MHz Pentium).
+** 1/95 -- Added Mac time manager routines for more accurate
+** timing on Macintosh (said to be good to 20 usecs) -- RG
+** 1/95 -- Re-did all the #defines so they made more
+** sense. See NMGLOBAL.H -- RG
+** 3/95 -- Fixed memory leak in LU decomposition. Did not
+** invalidate previous results, just made it easier to run.--RG
+** 3/95 -- Added TOOLHELP.DLL timing routine to Windows timer. --RG
+** 10/95 -- Added memory array & alignment; moved memory
+** allocation out of LU Decomposition -- RG
+**
+** DISCLAIMER
+** The source, executable, and documentation files that comprise
+** the BYTEmark benchmarks are made available on an "as is" basis.
+** This means that we at BYTE Magazine have made every reasonable
+** effort to verify that the there are no errors in the source and
+** executable code. We cannot, however, guarantee that the programs
+** are error-free. Consequently, McGraw-HIll and BYTE Magazine make
+** no claims in regard to the fitness of the source code, executable
+** code, and documentation of the BYTEmark.
+** Furthermore, BYTE Magazine, McGraw-Hill, and all employees
+** of McGraw-Hill cannot be held responsible for any damages resulting
+** from the use of this code or the results obtained from using
+** this code.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include "nmglobal.h"
+#include "cleanbench.h"
+#include "hardware.h"
+
+/*************
+**** main ****
+*************/
+int main(int argc, char *argv[]) {
+int i; /* Index */
+time_t time_and_date; /* Self-explanatory */
+struct tm *loctime;
+double bmean; /* Benchmark mean */
+double bstdev; /* Benchmark stdev */
+double lx_memindex; /* Linux memory index (mainly integer operations)*/
+double lx_intindex; /* Linux integer index */
+double lx_fpindex; /* Linux floating-point index */
+double intindex; /* Integer index */
+double fpindex; /* Floating-point index */
+unsigned long bnumrun; /* # of runs */
+
+/*
+** Set global parameters to default.
+*/
+global_min_ticks=MINIMUM_TICKS;
+global_min_seconds=MINIMUM_SECONDS;
+global_allstats=0;
+global_custrun=0;
+global_align=8;
+write_to_file=0;
+lx_memindex=(double)1.0; /* set for geometric mean computations */
+lx_intindex=(double)1.0;
+lx_fpindex=(double)1.0;
+intindex=(double)1.0;
+fpindex=(double)1.0;
+
+/*
+** We presume all tests will be run unless told
+** otherwise
+*/
+for(i=0;i<NUMTESTS;i++)
+ tests_to_do[i]=1;
+
+/*
+** Initialize test data structures to default
+** values.
+*/
+set_request_secs(); /* Set all request_secs fields */
+global_numsortstruct.adjust=0;
+global_numsortstruct.arraysize=NUMARRAYSIZE;
+
+global_strsortstruct.adjust=0;
+global_strsortstruct.arraysize=STRINGARRAYSIZE;
+
+global_bitopstruct.adjust=0;
+global_bitopstruct.bitfieldarraysize=BITFARRAYSIZE;
+
+global_emfloatstruct.adjust=0;
+global_emfloatstruct.arraysize=EMFARRAYSIZE;
+
+global_fourierstruct.adjust=0;
+
+global_assignstruct.adjust=0;
+
+global_ideastruct.adjust=0;
+global_ideastruct.arraysize=IDEAARRAYSIZE;
+
+global_huffstruct.adjust=0;
+global_huffstruct.arraysize=HUFFARRAYSIZE;
+
+global_nnetstruct.adjust=0;
+
+global_lustruct.adjust=0;
+
+/*
+** Handle any command-line arguments.
+*/
+if(argc>1)
+ for(i=1;i<argc;i++)
+ if(parse_arg(argv[i])==-1)
+ { display_help(argv[0]);
+ exit(0);
+ }
+/*
+** Output header
+*/
+puts("\nBYTEmark* Native Mode Benchmark ver. 2 (10/95)");
+puts("Index-split by Andrew D. Balsa (11/97)");
+puts("Linux/Unix* port by Uwe F. Mayer (12/96,11/97)");
+/*
+** See if the user wants all stats. Output heading info
+** if so.
+*/
+if(global_allstats)
+{
+ puts("\n============================== ALL STATISTICS ===============================");
+ time(&time_and_date);
+ loctime=localtime(&time_and_date);
+ printf("**Date and time of benchmark run: %s", asctime(loctime));
+ printf("**Sizeof: char:%d short:%u int:%u long:%u uint8_t:%u uint16_t:%u uint32_t:%u int32:%u\n",
+ sizeof(char),
+ sizeof(short),
+ sizeof(int),
+ sizeof(long),
+ sizeof(uint8_t),
+ sizeof(uint16_t),
+ sizeof(uint32_t),
+ sizeof(int32_t));
+#ifdef __linux__
+#include "sysinfo.c"
+#else
+ printf("**%s\n",sysname);
+ printf("**%s\n",compilername);
+ printf("**%s\n",compilerversion);
+#endif
+ puts("=============================================================================");
+}
+
+/*
+** Execute the tests.
+*/
+puts("\nTEST : Iterations/sec. : Old Index : New Index");
+puts(" : : Pentium 90* : AMD K6/233*");
+puts("--------------------:------------------:-------------:------------");
+
+for(i=0;i<NUMTESTS;i++)
+{
+ if(tests_to_do[i])
+ { printf("%s :",ftestnames[i]);
+ if (0!=bench_with_confidence(i,
+ &bmean,
+ &bstdev,
+ &bnumrun)){
+ puts("\n** WARNING: The current test result is NOT 95 % statistically certain.");
+ puts("** WARNING: The variation among the individual results is too large.");
+ printf(" :");
+ }
+ printf(" %15.5g : %9.2f : %9.2f\n",
+ bmean,bmean/bindex[i],bmean/lx_bindex[i]);
+ /*
+ ** Gather integer or FP indexes
+ */
+ if((i==4)||(i==8)||(i==9)){
+ /* FP index */
+ fpindex=fpindex*(bmean/bindex[i]);
+ /* Linux FP index */
+ lx_fpindex=lx_fpindex*(bmean/lx_bindex[i]);
+ }
+ else{
+ /* Integer index */
+ intindex=intindex*(bmean/bindex[i]);
+ if((i==0)||(i==3)||(i==6)||(i==7))
+ /* Linux integer index */
+ lx_intindex=lx_intindex*(bmean/lx_bindex[i]);
+ else
+ /* Linux memory index */
+ lx_memindex=lx_memindex*(bmean/lx_bindex[i]);
+ }
+
+ if(global_allstats)
+ {
+ printf(" Absolute standard deviation: %g\n",bstdev);
+ if (bmean>(double)1e-100){
+ /* avoid division by zero */
+ printf(" Relative standard deviation: %g %%\n",
+ (double)100*bstdev/bmean);
+ }
+ printf(" Number of runs: %lu\n",bnumrun);
+ show_stats(i);
+ printf("Done with %s\n\n",ftestnames[i]);
+ }
+ }
+}
+/* printf("...done...\n"); */
+
+/*
+** Output the total indexes
+*/
+if(global_custrun==0)
+{
+ puts("==========================ORIGINAL BYTEMARK RESULTS==========================");
+ printf("INTEGER INDEX : %.3f\n",
+ pow(intindex,(double).142857));
+ printf("FLOATING-POINT INDEX: %.3f\n",
+ pow(fpindex,(double).33333));
+ puts("Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0");
+#ifdef __linux__
+ puts("==============================LINUX DATA BELOW===============================");
+ hardware(write_to_file, global_ofile);
+#include "sysinfoc.c"
+ printf("MEMORY INDEX : %.3f\n",
+ pow(lx_memindex,(double).3333333333));
+ printf("INTEGER INDEX : %.3f\n",
+ pow(lx_intindex,(double).25));
+ printf("FLOATING-POINT INDEX: %.3f\n",
+ pow(lx_fpindex,(double).3333333333));
+ puts("Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38");
+#endif
+puts("* Trademarks are property of their respective holder.");
+}
+ return 0;
+}
+
+/**************
+** parse_arg **
+***************
+** Given a pointer to a string, we assume that's an argument.
+** Parse that argument and act accordingly.
+** Return 0 if ok, else return -1.
+*/
+static int parse_arg(char *argptr)
+{
+int i; /* Index */
+FILE *cfile; /* Command file identifier */
+
+/*
+** First character has got to be a hyphen.
+*/
+if(*argptr++!='-') return(-1);
+
+/*
+** Convert the rest of the argument to upper case
+** so there's little chance of confusion.
+*/
+for(i=0;i<strlen(argptr);i++)
+ argptr[i]=(char)toupper((int)argptr[i]);
+
+/*
+** Next character picks the action.
+*/
+switch(*argptr++)
+{
+ case '?': return(-1); /* Will display help */
+
+ case 'V': global_allstats=1; return(0); /* verbose mode */
+
+ case 'C': /* Command file name */
+ /*
+ ** First try to open the file for reading.
+ */
+ cfile=fopen(argptr,"r");
+ if(cfile==(FILE *)NULL)
+ { printf("**Error opening file: %s\n",argptr);
+ return(-1);
+ }
+ read_comfile(cfile); /* Read commands */
+ fclose(cfile);
+ break;
+ default:
+ return(-1);
+}
+return(0);
+}
+
+/*******************
+** display_help() **
+********************
+** Display a help message showing argument requirements and such.
+** Exit when you're done...I mean, REALLY exit.
+*/
+void display_help(char *progname)
+{
+ printf("Usage: %s [-v] [-c<FILE>]\n",progname);
+ printf(" -v = verbose\n");
+ printf(" -c = input parameters thru command file <FILE>\n");
+ exit(0);
+}
+
+
+/*****************
+** read_comfile **
+******************
+** Read the command file. Set global parameters as
+** specified. This routine assumes that the command file
+** is already open.
+*/
+static void read_comfile(FILE *cfile)
+{
+char inbuf[40];
+char *eptr; /* Offset to "=" sign */
+int i; /* Index */
+
+/*
+** Sit in a big loop, reading a line from the file at each
+** pass. Terminate on EOF.
+*/
+while(fgets(inbuf,39,cfile)!=(char *)NULL)
+{
+ /* Overwrite the CR character */
+ if(strlen(inbuf)>0)
+ inbuf[strlen(inbuf)-1]='\0';
+
+ /*
+ ** Parse up to the "=" sign. If we don't find an
+ ** "=", then flag an error.
+ */
+ if((eptr=strchr(inbuf,(int)'='))==(char *)NULL)
+ { printf("**COMMAND FILE ERROR at LINE:\n %s\n",
+ inbuf);
+ goto skipswitch; /* A GOTO!!!! */
+ }
+
+ /*
+ ** Insert a null where the "=" was, then convert
+ ** the substring to uppercase. That will enable
+ ** us to perform the match.
+ */
+ *eptr++='\0';
+ strtoupper((char *)&inbuf[0]);
+ i=MAXPARAM;
+ do {
+ if(strcmp(inbuf,paramnames[i])==0)
+ break;
+ } while(--i>=0);
+
+ if(i<0)
+ { printf("**COMMAND FILE ERROR -- UNKNOWN PARAM: %s",
+ inbuf);
+ goto skipswitch;
+ }
+
+ /*
+ ** Advance eptr to the next field...which should be
+ ** the value assigned to the parameter.
+ */
+ switch(i)
+ {
+ case PF_GMTICKS: /* GLOBALMINTICKS */
+ global_min_ticks=(unsigned long)atol(eptr);
+ break;
+
+ case PF_MINSECONDS: /* MINSECONDS */
+ global_min_seconds=(unsigned long)atol(eptr);
+ set_request_secs();
+ break;
+
+ case PF_ALLSTATS: /* ALLSTATS */
+ global_allstats=getflag(eptr);
+ break;
+
+ case PF_OUTFILE: /* OUTFILE */
+ strcpy(global_ofile_name,eptr);
+ global_ofile=fopen(global_ofile_name,"a");
+ /*
+ ** Open the output file.
+ */
+ if(global_ofile==(FILE *)NULL)
+ { printf("**Error opening output file: %s\n",
+ global_ofile_name);
+ exit(1);
+ }
+ write_to_file=-1;
+ break;
+
+ case PF_CUSTOMRUN: /* CUSTOMRUN */
+ global_custrun=getflag(eptr);
+ for(i=0;i<NUMTESTS;i++)
+ tests_to_do[i]=1-global_custrun;
+ break;
+
+ case PF_DONUM: /* DONUMSORT */
+ tests_to_do[TF_NUMSORT]=getflag(eptr);
+ break;
+
+ case PF_NUMNUMA: /* NUMNUMARRAYS */
+ global_numsortstruct.numarrays=
+ (ushort)atoi(eptr);
+ global_numsortstruct.adjust=1;
+ break;
+
+ case PF_NUMASIZE: /* NUMARRAYSIZE */
+ global_numsortstruct.arraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_NUMMINS: /* NUMMINSECONDS */
+ global_numsortstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOSTR: /* DOSTRINGSORT */
+ tests_to_do[TF_SSORT]=getflag(eptr);
+ break;
+
+ case PF_STRASIZE: /* STRARRAYSIZE */
+ global_strsortstruct.arraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_NUMSTRA: /* NUMSTRARRAYS */
+ global_strsortstruct.numarrays=
+ (ushort)atoi(eptr);
+ global_strsortstruct.adjust=1;
+ break;
+
+ case PF_STRMINS: /* STRMINSECONDS */
+ global_strsortstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOBITF: /* DOBITFIELD */
+ tests_to_do[TF_BITOP]=getflag(eptr);
+ break;
+
+ case PF_NUMBITOPS: /* NUMBITOPS */
+ global_bitopstruct.bitoparraysize=
+ (unsigned long)atol(eptr);
+ global_bitopstruct.adjust=1;
+ break;
+
+ case PF_BITFSIZE: /* BITFIELDSIZE */
+ global_bitopstruct.bitfieldarraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_BITMINS: /* BITMINSECONDS */
+ global_bitopstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOEMF: /* DOEMF */
+ tests_to_do[TF_FPEMU]=getflag(eptr);
+ break;
+
+ case PF_EMFASIZE: /* EMFARRAYSIZE */
+ global_emfloatstruct.arraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_EMFLOOPS: /* EMFLOOPS */
+ global_emfloatstruct.loops=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_EMFMINS: /* EMFMINSECOND */
+ global_emfloatstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOFOUR: /* DOFOUR */
+ tests_to_do[TF_FFPU]=getflag(eptr);
+ break;
+
+ case PF_FOURASIZE: /* FOURASIZE */
+ global_fourierstruct.arraysize=
+ (unsigned long)atol(eptr);
+ global_fourierstruct.adjust=1;
+ break;
+
+ case PF_FOURMINS: /* FOURMINSECONDS */
+ global_fourierstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOASSIGN: /* DOASSIGN */
+ tests_to_do[TF_ASSIGN]=getflag(eptr);
+ break;
+
+ case PF_AARRAYS: /* ASSIGNARRAYS */
+ global_assignstruct.numarrays=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_ASSIGNMINS: /* ASSIGNMINSECONDS */
+ global_assignstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOIDEA: /* DOIDEA */
+ tests_to_do[TF_IDEA]=getflag(eptr);
+ break;
+
+ case PF_IDEAASIZE: /* IDEAARRAYSIZE */
+ global_ideastruct.arraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_IDEALOOPS: /* IDEALOOPS */
+ global_ideastruct.loops=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_IDEAMINS: /* IDEAMINSECONDS */
+ global_ideastruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOHUFF: /* DOHUFF */
+ tests_to_do[TF_HUFF]=getflag(eptr);
+ break;
+
+ case PF_HUFFASIZE: /* HUFFARRAYSIZE */
+ global_huffstruct.arraysize=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_HUFFLOOPS: /* HUFFLOOPS */
+ global_huffstruct.loops=
+ (unsigned long)atol(eptr);
+ global_huffstruct.adjust=1;
+ break;
+
+ case PF_HUFFMINS: /* HUFFMINSECONDS */
+ global_huffstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DONNET: /* DONNET */
+ tests_to_do[TF_NNET]=getflag(eptr);
+ break;
+
+ case PF_NNETLOOPS: /* NNETLOOPS */
+ global_nnetstruct.loops=
+ (unsigned long)atol(eptr);
+ global_nnetstruct.adjust=1;
+ break;
+
+ case PF_NNETMINS: /* NNETMINSECONDS */
+ global_nnetstruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_DOLU: /* DOLU */
+ tests_to_do[TF_LU]=getflag(eptr);
+ break;
+
+ case PF_LUNARRAYS: /* LUNUMARRAYS */
+ global_lustruct.numarrays=
+ (unsigned long)atol(eptr);
+ global_lustruct.adjust=1;
+ break;
+
+ case PF_LUMINS: /* LUMINSECONDS */
+ global_lustruct.request_secs=
+ (unsigned long)atol(eptr);
+ break;
+
+ case PF_ALIGN: /* ALIGN */
+ global_align=atoi(eptr);
+ break;
+ }
+skipswitch:
+ continue;
+} /* End while */
+
+return;
+}
+
+/************
+** getflag **
+*************
+** Return 1 if cptr points to "T"; 0 otherwise.
+*/
+static int getflag(char *cptr)
+{
+ if(toupper((int)*cptr)=='T') return(1);
+return(0);
+}
+
+/***************
+** strtoupper **
+****************
+** Convert's a string to upper case. The string is presumed
+** to consist only of alphabetic characters, and to be terminated
+** with a null.
+*/
+static void strtoupper(char *s)
+{
+
+do {
+/*
+** Oddly enough, the following line did not work under THINK C.
+** So, I modified it....hmmmm. --RG
+ *s++=(char)toupper((int)*s);
+*/
+ *s=(char)toupper((int)*s);
+ s++;
+} while(*s!=(char)'\0');
+return;
+}
+
+/*********************
+** set_request_secs **
+**********************
+** Set everyone's "request_secs" entry to whatever
+** value is in global_min_secs. This is done
+** at the beginning, and possibly later if the
+** user redefines global_min_secs in the command file.
+*/
+static void set_request_secs(void)
+{
+
+global_numsortstruct.request_secs=global_min_seconds;
+global_strsortstruct.request_secs=global_min_seconds;
+global_bitopstruct.request_secs=global_min_seconds;
+global_emfloatstruct.request_secs=global_min_seconds;
+global_fourierstruct.request_secs=global_min_seconds;
+global_assignstruct.request_secs=global_min_seconds;
+global_ideastruct.request_secs=global_min_seconds;
+global_huffstruct.request_secs=global_min_seconds;
+global_nnetstruct.request_secs=global_min_seconds;
+global_lustruct.request_secs=global_min_seconds;
+
+return;
+}
+
+
+/**************************
+** bench_with_confidence **
+***************************
+** Given a benchmark id that indicates a function, this routine
+** repeatedly calls that benchmark, seeking to collect and replace
+** scores to get 5 that meet the confidence criteria.
+**
+** The above is mathematically questionable, as the statistical theory
+** depends on independent observations, and if we exchange data points
+** depending on what we already have then this certainly violates
+** independence of the observations. Hence I changed this so that at
+** most 30 observations are done, but none are deleted as we go
+** along. We simply do more runs and hope to get a big enough sample
+** size so that things stabilize. Uwe F. Mayer
+**
+** Return 0 if ok, -1 if failure. Returns mean
+** and std. deviation of results if successful.
+*/
+static int bench_with_confidence(int fid, /* Function id */
+ double *mean, /* Mean of scores */
+ double *stdev, /* Standard deviation */
+ unsigned long *numtries) /* # of attempts */
+{
+double myscores[30]; /* Need at least 5 scores, use at most 30 */
+double c_half_interval; /* Confidence half interval */
+int i; /* Index */
+/* double newscore; */ /* For improving confidence interval */
+
+/*
+** Get first 5 scores. Then begin confidence testing.
+*/
+for (i=0;i<5;i++)
+{ (*funcpointer[fid])();
+ myscores[i]=getscore(fid);
+}
+*numtries=5; /* Show 5 attempts */
+
+/*
+** The system allows a maximum of 30 tries before it gives
+** up. Since we've done 5 already, we'll allow 25 more.
+*/
+
+/*
+** Enter loop to test for confidence criteria.
+*/
+while(1)
+{
+ /*
+ ** Calculate confidence. Should always return 0.
+ */
+ if (0!=calc_confidence(myscores,
+ *numtries,
+ &c_half_interval,
+ mean,
+ stdev)) return(-1);
+
+ /*
+ ** Is the length of the half interval 5% or less of mean?
+ ** If so, we can go home. Otherwise, we have to continue.
+ */
+ if(c_half_interval/ (*mean) <= (double)0.05)
+ break;
+
+ /* We now simply add a new test run and hope that the runs
+ finally stabilize, Uwe F. Mayer */
+ if(*numtries==30) return(-1);
+ (*funcpointer[fid])();
+ myscores[*numtries]=getscore(fid);
+ *numtries+=1;
+}
+
+ return 0;
+}
+
+/********************
+** calc_confidence **
+*********************
+** Given a set of numtries scores, calculate the confidence
+** half-interval. We'll also return the sample mean and sample
+** standard deviation.
+** NOTE: This routines presumes a confidence of 95% and
+** a confidence coefficient of .95
+** returns 0 if there is an error, otherwise -1
+*/
+static int calc_confidence(double scores[], /* Array of scores */
+ int num_scores, /* number of scores in array */
+ double *c_half_interval, /* Confidence half-int */
+ double *smean, /* Standard mean */
+ double *sdev) /* Sample stand dev */
+{
+/* Here is a list of the student-t distribution up to 29 degrees of
+ freedom. The value at 0 is bogus, as there is no value for zero
+ degrees of freedom. */
+double student_t[30]={0.0 , 12.706 , 4.303 , 3.182 , 2.776 , 2.571 ,
+ 2.447 , 2.365 , 2.306 , 2.262 , 2.228 ,
+ 2.201 , 2.179 , 2.160 , 2.145 , 2.131 ,
+ 2.120 , 2.110 , 2.101 , 2.093 , 2.086 ,
+ 2.080 , 2.074 , 2.069 , 2.064 , 2.060 ,
+ 2.056 , 2.052 , 2.048 , 2.045 };
+int i; /* Index */
+if ((num_scores<2) || (num_scores>30)) {
+ puts("Internal error: calc_confidence called with an illegal number of scores");
+ return(-1);
+}
+/*
+** First calculate mean.
+*/
+*smean=(double)0.0;
+for(i=0;i<num_scores;i++){
+ *smean+=scores[i];
+}
+*smean/=(double)num_scores;
+
+/* Get standard deviation */
+*sdev=(double)0.0;
+for(i=0;i<num_scores;i++) {
+ *sdev+=(scores[i]-(*smean))*(scores[i]-(*smean));
+}
+*sdev/=(double)(num_scores-1);
+*sdev=sqrt(*sdev);
+
+/* Now calculate the length of the confidence half-interval. For a
+** confidence level of 95% our confidence coefficient gives us a
+** multiplying factor of the upper .025 quartile of a t distribution
+** with num_scores-1 degrees of freedom, and dividing by sqrt(number of
+** observations). See any introduction to statistics.
+*/
+*c_half_interval=student_t[num_scores-1] * (*sdev) / sqrt((double)num_scores);
+return(0);
+}
+
+/*************
+** getscore **
+**************
+** Return the score for a particular benchmark.
+*/
+static double getscore(int fid) {
+ /*
+ ** Fid tells us the function. This is really a matter of
+ ** doing the proper coercion.
+ */
+ switch(fid) {
+ case TF_NUMSORT:
+ return(global_numsortstruct.sortspersec);
+ case TF_SSORT:
+ return(global_strsortstruct.sortspersec);
+ case TF_BITOP:
+ return(global_bitopstruct.bitopspersec);
+ case TF_FPEMU:
+ return(global_emfloatstruct.emflops);
+ case TF_FFPU:
+ return(global_fourierstruct.fflops);
+ case TF_ASSIGN:
+ return(global_assignstruct.iterspersec);
+ case TF_IDEA:
+ return(global_ideastruct.iterspersec);
+ case TF_HUFF:
+ return(global_huffstruct.iterspersec);
+ case TF_NNET:
+ return(global_nnetstruct.iterspersec);
+ case TF_LU:
+ return(global_lustruct.iterspersec);
+ }
+ return 0.0;
+}
+
+/***************
+** show_stats **
+****************
+** This routine displays statistics for a particular benchmark.
+** The benchmark is identified by its id.
+*/
+static void show_stats (int bid) {
+ switch(bid) {
+ case TF_NUMSORT: /* Numeric sort */
+ printf(" Number of arrays: %d\n", global_numsortstruct.numarrays);
+ printf(" Array size: %ld\n", global_numsortstruct.arraysize);
+ break;
+ case TF_SSORT: /* String sort */
+ printf(" Number of arrays: %d\n", global_strsortstruct.numarrays);
+ printf(" Array size: %ld\n", global_strsortstruct.arraysize);
+ break;
+ case TF_BITOP: /* Bitmap operation */
+ printf(" Operations array size: %ld\n", global_bitopstruct.bitoparraysize);
+ printf(" Bitfield array size: %ld\n", global_bitopstruct.bitfieldarraysize);
+ break;
+ case TF_FPEMU: /* Floating-point emulation */
+ printf(" Number of loops: %lu\n", global_emfloatstruct.loops);
+ printf(" Array size: %lu\n", global_emfloatstruct.arraysize);
+ break;
+ case TF_FFPU: /* Fourier test */
+ printf(" Number of coefficients: %lu\n", global_fourierstruct.arraysize);
+ break;
+ case TF_ASSIGN:
+ printf(" Number of arrays: %lu\n", global_assignstruct.numarrays);
+ break;
+ case TF_IDEA:
+ printf(" Array size: %lu\n", global_ideastruct.arraysize);
+ printf(" Number of loops: %lu\n", global_ideastruct.loops);
+ break;
+ case TF_HUFF:
+ printf(" Array size: %lu\n", global_huffstruct.arraysize);
+ printf(" Number of loops: %lu\n", global_huffstruct.loops);
+ break;
+ case TF_NNET:
+ printf(" Number of loops: %lu\n", global_nnetstruct.loops);
+ break;
+ case TF_LU:
+ printf(" Number of arrays: %lu\n", global_lustruct.numarrays);
+ break;
+ }
+ return;
+}