/* ** nbench0.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 #include #include #include #include #include #include "nmglobal.h" #include "nbench0.h" #include "hardware.h" /************* **** main **** *************/ #ifdef MAC void main(void) #else int main(int argc, char *argv[]) #endif { 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 */ ulong bnumrun; /* # of runs */ #ifdef MAC MaxApplZone(); #endif #ifdef MACTIMEMGR /* Set up high res timer */ MacHSTdelay=600*1000*1000; /* Delay is 10 minutes */ memset((char *)&myTMTask,0,sizeof(TMTask)); /* Prime and remove the task, calculating overhead */ PrimeTime((QElemPtr)&myTMTask,-MacHSTdelay); RmvTime((QElemPtr)&myTMTask); MacHSTohead=MacHSTdelay+myTMTask.tmCount; #endif #ifdef WIN31TIMER /* Set up the size of the timer info structure */ win31tinfo.dwSize=(DWORD)sizeof(TIMERINFO); /* Load library */ if((hThlp=LoadLibrary("TOOLHELP.DLL"))<32) { printf("Error loading TOOLHELP\n"); exit(0); } if(!(lpfn=GetProcAddress(hThlp,"TimerCount"))) { printf("TOOLHELP error\n"); exit(0); } #endif /* ** 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; mem_array_ents=0; /* Nothing in mem array */ /* ** We presume all tests will be run unless told ** otherwise */ for(i=0;i1) for(i=1;i(double)1e-100){ /* avoid division by zero */ sprintf(buffer," Relative standard deviation: %g %%\n", (double)100*bstdev/bmean); output_string(buffer); } sprintf(buffer," Number of runs: %lu\n",bnumrun); output_string(buffer); show_stats(i); sprintf(buffer,"Done with %s\n\n",ftestnames[i]); output_string(buffer); } } } /* printf("...done...\n"); */ /* ** Output the total indexes */ if(global_custrun==0) { output_string("==========================ORIGINAL BYTEMARK RESULTS==========================\n"); sprintf(buffer,"INTEGER INDEX : %.3f\n", pow(intindex,(double).142857)); output_string(buffer); sprintf(buffer,"FLOATING-POINT INDEX: %.3f\n", pow(fpindex,(double).33333)); output_string(buffer); output_string("Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0\n"); #ifdef LINUX output_string("==============================LINUX DATA BELOW===============================\n"); hardware(write_to_file, global_ofile); #include "sysinfoc.c" sprintf(buffer,"MEMORY INDEX : %.3f\n", pow(lx_memindex,(double).3333333333)); output_string(buffer); sprintf(buffer,"INTEGER INDEX : %.3f\n", pow(lx_intindex,(double).25)); output_string(buffer); sprintf(buffer,"FLOATING-POINT INDEX: %.3f\n", pow(lx_fpindex,(double).3333333333)); output_string(buffer); output_string("Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38\n"); #endif output_string("* Trademarks are property of their respective holder.\n"); } exit(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]\n",progname); printf(" -v = verbose\n"); printf(" -c = input parameters thru command 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=(ulong)atol(eptr); break; case PF_MINSECONDS: /* MINSECONDS */ global_min_seconds=(ulong)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); ErrorExit(); } write_to_file=-1; break; case PF_CUSTOMRUN: /* CUSTOMRUN */ global_custrun=getflag(eptr); for(i=0;i*sdev) { is_beaten=i; sdev_to_beat=*sdev; } } if(is_beaten!=-1) { scores[is_beaten]=*newscore; return(-1); } return(0); } #endif /******************** ** 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)) { output_string("Internal error: calc_confidence called with an illegal number of scores\n"); return(-1); } /* ** First calculate mean. */ *smean=(double)0.0; for(i=0;i