6 /*******************************************
8 ** BYTE MAGAZINE'S NATIVE MODE BENCHMARKS **
11 ** Rick Grehan, BYTE Magazine **
12 ********************************************
13 ** NOTE: These benchmarks do NOT check for the presence
14 ** of an FPU. You have to find that out manually.
16 ** REVISION HISTORY FOR BENCHMARKS
17 ** 9/94 -- First beta. --RG
18 ** 12/94 -- Bug discovered in some of the integer routines
19 ** (IDEA, Huffman,...). Routines were not accurately counting
20 ** the number of loops. Fixed. --RG (Thanks to Steve A.)
21 ** 12/94 -- Added routines to calculate and display index
22 ** values. Indexes based on DELL XPS 90 (90 MHz Pentium).
23 ** 1/95 -- Added Mac time manager routines for more accurate
24 ** timing on Macintosh (said to be good to 20 usecs) -- RG
25 ** 1/95 -- Re-did all the #defines so they made more
26 ** sense. See NMGLOBAL.H -- RG
27 ** 3/95 -- Fixed memory leak in LU decomposition. Did not
28 ** invalidate previous results, just made it easier to run.--RG
29 ** 3/95 -- Added TOOLHELP.DLL timing routine to Windows timer. --RG
30 ** 10/95 -- Added memory array & alignment; moved memory
31 ** allocation out of LU Decomposition -- RG
34 ** The source, executable, and documentation files that comprise
35 ** the BYTEmark benchmarks are made available on an "as is" basis.
36 ** This means that we at BYTE Magazine have made every reasonable
37 ** effort to verify that the there are no errors in the source and
38 ** executable code. We cannot, however, guarantee that the programs
39 ** are error-free. Consequently, McGraw-HIll and BYTE Magazine make
40 ** no claims in regard to the fitness of the source code, executable
41 ** code, and documentation of the BYTEmark.
42 ** Furthermore, BYTE Magazine, McGraw-Hill, and all employees
43 ** of McGraw-Hill cannot be held responsible for any damages resulting
44 ** from the use of this code or the results obtained from using
64 int main(int argc, char *argv[])
68 time_t time_and_date; /* Self-explanatory */
70 double bmean; /* Benchmark mean */
71 double bstdev; /* Benchmark stdev */
72 double lx_memindex; /* Linux memory index (mainly integer operations)*/
73 double lx_intindex; /* Linux integer index */
74 double lx_fpindex; /* Linux floating-point index */
75 double intindex; /* Integer index */
76 double fpindex; /* Floating-point index */
77 ulong bnumrun; /* # of runs */
84 /* Set up high res timer */
85 MacHSTdelay=600*1000*1000; /* Delay is 10 minutes */
87 memset((char *)&myTMTask,0,sizeof(TMTask));
89 /* Prime and remove the task, calculating overhead */
90 PrimeTime((QElemPtr)&myTMTask,-MacHSTdelay);
91 RmvTime((QElemPtr)&myTMTask);
92 MacHSTohead=MacHSTdelay+myTMTask.tmCount;
96 /* Set up the size of the timer info structure */
97 win31tinfo.dwSize=(DWORD)sizeof(TIMERINFO);
99 if((hThlp=LoadLibrary("TOOLHELP.DLL"))<32)
100 { printf("Error loading TOOLHELP\n");
103 if(!(lpfn=GetProcAddress(hThlp,"TimerCount")))
104 { printf("TOOLHELP error\n");
110 ** Set global parameters to default.
112 global_min_ticks=MINIMUM_TICKS;
113 global_min_seconds=MINIMUM_SECONDS;
118 lx_memindex=(double)1.0; /* set for geometric mean computations */
119 lx_intindex=(double)1.0;
120 lx_fpindex=(double)1.0;
121 intindex=(double)1.0;
123 mem_array_ents=0; /* Nothing in mem array */
126 ** We presume all tests will be run unless told
129 for(i=0;i<NUMTESTS;i++)
133 ** Initialize test data structures to default
136 set_request_secs(); /* Set all request_secs fields */
137 global_numsortstruct.adjust=0;
138 global_numsortstruct.arraysize=NUMARRAYSIZE;
140 global_strsortstruct.adjust=0;
141 global_strsortstruct.arraysize=STRINGARRAYSIZE;
143 global_bitopstruct.adjust=0;
144 global_bitopstruct.bitfieldarraysize=BITFARRAYSIZE;
146 global_emfloatstruct.adjust=0;
147 global_emfloatstruct.arraysize=EMFARRAYSIZE;
149 global_fourierstruct.adjust=0;
151 global_assignstruct.adjust=0;
153 global_ideastruct.adjust=0;
154 global_ideastruct.arraysize=IDEAARRAYSIZE;
156 global_huffstruct.adjust=0;
157 global_huffstruct.arraysize=HUFFARRAYSIZE;
159 global_nnetstruct.adjust=0;
161 global_lustruct.adjust=0;
164 ** For Macintosh -- read the command line.
171 ** Handle any command-line arguments.
175 if(parse_arg(argv[i])==-1)
176 { display_help(argv[0]);
183 output_string("\nBYTEmark* Native Mode Benchmark ver. 2 (10/95)\n");
184 output_string("Index-split by Andrew D. Balsa (11/97)\n");
185 output_string("Linux/Unix* port by Uwe F. Mayer (12/96,11/97)\n");
187 output_string("BBBBBB YYY Y TTTTTTT EEEEEEE\n");
188 output_string("BBB B YYY Y TTT EEE\n");
189 output_string("BBB B YYY Y TTT EEE\n");
190 output_string("BBBBBB YYY Y TTT EEEEEEE\n");
191 output_string("BBB B YYY TTT EEE\n");
192 output_string("BBB B YYY TTT EEE\n");
193 output_string("BBBBBB YYY TTT EEEEEEE\n\n");
194 output_string("\nBYTEmark (tm) Native Mode Benchmark ver. 2 (10/95)\n");
197 ** See if the user wants all stats. Output heading info
203 output_string("============================== ALL STATISTICS ===============================\n");
204 time(&time_and_date);
205 loctime=localtime(&time_and_date);
206 sprintf(buffer,"**Date and time of benchmark run: %s",asctime(loctime));
207 output_string(buffer);
208 sprintf(buffer,"**Sizeof: char:%u short:%u int:%u long:%u u8:%u u16:%u u32:%u int32:%u\n",
209 (unsigned int)sizeof(char),
210 (unsigned int)sizeof(short),
211 (unsigned int)sizeof(int),
212 (unsigned int)sizeof(long),
213 (unsigned int)sizeof(u8),
214 (unsigned int)sizeof(u16),
215 (unsigned int)sizeof(u32),
216 (unsigned int)sizeof(int32));
217 output_string(buffer);
221 sprintf(buffer,"**%s\n",sysname);
222 output_string(buffer);
223 sprintf(buffer,"**%s\n",compilername);
224 output_string(buffer);
225 sprintf(buffer,"**%s\n",compilerversion);
226 output_string(buffer);
228 output_string("=============================================================================\n");
232 ** Execute the tests.
235 output_string("\nTEST : Iterations/sec. : Old Index : New Index\n");
236 output_string(" : : Pentium 90* : AMD K6/233*\n");
237 output_string("--------------------:------------------:-------------:------------\n");
240 for(i=0;i<NUMTESTS;i++)
243 { sprintf(buffer,"%s :",ftestnames[i]);
244 output_string(buffer);
245 if (0!=bench_with_confidence(i,
249 output_string("\n** WARNING: The current test result is NOT 95 % statistically certain.\n");
250 output_string("** WARNING: The variation among the individual results is too large.\n");
254 sprintf(buffer," %15.5g : %9.2f : %9.2f\n",
255 bmean,bmean/bindex[i],bmean/lx_bindex[i]);
257 sprintf(buffer," Iterations/sec.: %13.2f Index: %6.2f\n",
258 bmean,bmean/bindex[i]);
260 output_string(buffer);
262 ** Gather integer or FP indexes
264 if((i==4)||(i==8)||(i==9)){
266 fpindex=fpindex*(bmean/bindex[i]);
268 lx_fpindex=lx_fpindex*(bmean/lx_bindex[i]);
272 intindex=intindex*(bmean/bindex[i]);
273 if((i==0)||(i==3)||(i==6)||(i==7))
274 /* Linux integer index */
275 lx_intindex=lx_intindex*(bmean/lx_bindex[i]);
277 /* Linux memory index */
278 lx_memindex=lx_memindex*(bmean/lx_bindex[i]);
283 sprintf(buffer," Absolute standard deviation: %g\n",bstdev);
284 output_string(buffer);
285 if (bmean>(double)1e-100){
286 /* avoid division by zero */
287 sprintf(buffer," Relative standard deviation: %g %%\n",
288 (double)100*bstdev/bmean);
289 output_string(buffer);
291 sprintf(buffer," Number of runs: %lu\n",bnumrun);
292 output_string(buffer);
294 sprintf(buffer,"Done with %s\n\n",ftestnames[i]);
295 output_string(buffer);
299 /* printf("...done...\n"); */
302 ** Output the total indexes
304 if(global_custrun==0)
306 output_string("==========================ORIGINAL BYTEMARK RESULTS==========================\n");
307 sprintf(buffer,"INTEGER INDEX : %.3f\n",
308 pow(intindex,(double).142857));
309 output_string(buffer);
310 sprintf(buffer,"FLOATING-POINT INDEX: %.3f\n",
311 pow(fpindex,(double).33333));
312 output_string(buffer);
313 output_string("Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0\n");
315 output_string("==============================LINUX DATA BELOW===============================\n");
316 hardware(write_to_file, global_ofile);
317 #include "sysinfoc.c"
318 sprintf(buffer,"MEMORY INDEX : %.3f\n",
319 pow(lx_memindex,(double).3333333333));
320 output_string(buffer);
321 sprintf(buffer,"INTEGER INDEX : %.3f\n",
322 pow(lx_intindex,(double).25));
323 output_string(buffer);
324 sprintf(buffer,"FLOATING-POINT INDEX: %.3f\n",
325 pow(lx_fpindex,(double).3333333333));
326 output_string(buffer);
327 output_string("Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38\n");
329 output_string("* Trademarks are property of their respective holder.\n");
338 ** Given a pointer to a string, we assume that's an argument.
339 ** Parse that argument and act accordingly.
340 ** Return 0 if ok, else return -1.
342 static int parse_arg(char *argptr)
345 FILE *cfile; /* Command file identifier */
348 ** First character has got to be a hyphen.
350 if(*argptr++!='-') return(-1);
353 ** Convert the rest of the argument to upper case
354 ** so there's little chance of confusion.
356 for(i=0;i<strlen(argptr);i++)
357 argptr[i]=(char)toupper((int)argptr[i]);
360 ** Next character picks the action.
364 case '?': return(-1); /* Will display help */
366 case 'V': global_allstats=1; return(0); /* verbose mode */
368 case 'C': /* Command file name */
370 ** First try to open the file for reading.
372 cfile=fopen(argptr,"r");
373 if(cfile==(FILE *)NULL)
374 { printf("**Error opening file: %s\n",argptr);
377 read_comfile(cfile); /* Read commands */
389 ** Display a help message showing argument requirements and such.
390 ** Exit when you're done...I mean, REALLY exit.
392 void display_help(char *progname)
394 printf("Usage: %s [-v] [-c<FILE>]\n",progname);
395 printf(" -v = verbose\n");
396 printf(" -c = input parameters thru command file <FILE>\n");
404 ** Read the command file. Set global parameters as
405 ** specified. This routine assumes that the command file
408 static void read_comfile(FILE *cfile)
411 char *eptr; /* Offset to "=" sign */
415 ** Sit in a big loop, reading a line from the file at each
416 ** pass. Terminate on EOF.
418 while(fgets(inbuf,39,cfile)!=(char *)NULL)
420 /* Overwrite the CR character */
422 inbuf[strlen(inbuf)-1]='\0';
425 ** Parse up to the "=" sign. If we don't find an
426 ** "=", then flag an error.
428 if((eptr=strchr(inbuf,(int)'='))==(char *)NULL)
429 { printf("**COMMAND FILE ERROR at LINE:\n %s\n",
431 goto skipswitch; /* A GOTO!!!! */
435 ** Insert a null where the "=" was, then convert
436 ** the substring to uppercase. That will enable
437 ** us to perform the match.
440 strtoupper((char *)&inbuf[0]);
443 if(strcmp(inbuf,paramnames[i])==0)
448 { printf("**COMMAND FILE ERROR -- UNKNOWN PARAM: %s",
454 ** Advance eptr to the next field...which should be
455 ** the value assigned to the parameter.
459 case PF_GMTICKS: /* GLOBALMINTICKS */
460 global_min_ticks=(ulong)atol(eptr);
463 case PF_MINSECONDS: /* MINSECONDS */
464 global_min_seconds=(ulong)atol(eptr);
468 case PF_ALLSTATS: /* ALLSTATS */
469 global_allstats=getflag(eptr);
472 case PF_OUTFILE: /* OUTFILE */
473 strcpy(global_ofile_name,eptr);
474 global_ofile=fopen(global_ofile_name,"a");
476 ** Open the output file.
478 if(global_ofile==(FILE *)NULL)
479 { printf("**Error opening output file: %s\n",
486 case PF_CUSTOMRUN: /* CUSTOMRUN */
487 global_custrun=getflag(eptr);
488 for(i=0;i<NUMTESTS;i++)
489 tests_to_do[i]=1-global_custrun;
492 case PF_DONUM: /* DONUMSORT */
493 tests_to_do[TF_NUMSORT]=getflag(eptr);
496 case PF_NUMNUMA: /* NUMNUMARRAYS */
497 global_numsortstruct.numarrays=
499 global_numsortstruct.adjust=1;
502 case PF_NUMASIZE: /* NUMARRAYSIZE */
503 global_numsortstruct.arraysize=
507 case PF_NUMMINS: /* NUMMINSECONDS */
508 global_numsortstruct.request_secs=
512 case PF_DOSTR: /* DOSTRINGSORT */
513 tests_to_do[TF_SSORT]=getflag(eptr);
516 case PF_STRASIZE: /* STRARRAYSIZE */
517 global_strsortstruct.arraysize=
521 case PF_NUMSTRA: /* NUMSTRARRAYS */
522 global_strsortstruct.numarrays=
524 global_strsortstruct.adjust=1;
527 case PF_STRMINS: /* STRMINSECONDS */
528 global_strsortstruct.request_secs=
532 case PF_DOBITF: /* DOBITFIELD */
533 tests_to_do[TF_BITOP]=getflag(eptr);
536 case PF_NUMBITOPS: /* NUMBITOPS */
537 global_bitopstruct.bitoparraysize=
539 global_bitopstruct.adjust=1;
542 case PF_BITFSIZE: /* BITFIELDSIZE */
543 global_bitopstruct.bitfieldarraysize=
547 case PF_BITMINS: /* BITMINSECONDS */
548 global_bitopstruct.request_secs=
552 case PF_DOEMF: /* DOEMF */
553 tests_to_do[TF_FPEMU]=getflag(eptr);
556 case PF_EMFASIZE: /* EMFARRAYSIZE */
557 global_emfloatstruct.arraysize=
561 case PF_EMFLOOPS: /* EMFLOOPS */
562 global_emfloatstruct.loops=
566 case PF_EMFMINS: /* EMFMINSECOND */
567 global_emfloatstruct.request_secs=
571 case PF_DOFOUR: /* DOFOUR */
572 tests_to_do[TF_FFPU]=getflag(eptr);
575 case PF_FOURASIZE: /* FOURASIZE */
576 global_fourierstruct.arraysize=
578 global_fourierstruct.adjust=1;
581 case PF_FOURMINS: /* FOURMINSECONDS */
582 global_fourierstruct.request_secs=
586 case PF_DOASSIGN: /* DOASSIGN */
587 tests_to_do[TF_ASSIGN]=getflag(eptr);
590 case PF_AARRAYS: /* ASSIGNARRAYS */
591 global_assignstruct.numarrays=
595 case PF_ASSIGNMINS: /* ASSIGNMINSECONDS */
596 global_assignstruct.request_secs=
600 case PF_DOIDEA: /* DOIDEA */
601 tests_to_do[TF_IDEA]=getflag(eptr);
604 case PF_IDEAASIZE: /* IDEAARRAYSIZE */
605 global_ideastruct.arraysize=
609 case PF_IDEALOOPS: /* IDEALOOPS */
610 global_ideastruct.loops=
614 case PF_IDEAMINS: /* IDEAMINSECONDS */
615 global_ideastruct.request_secs=
619 case PF_DOHUFF: /* DOHUFF */
620 tests_to_do[TF_HUFF]=getflag(eptr);
623 case PF_HUFFASIZE: /* HUFFARRAYSIZE */
624 global_huffstruct.arraysize=
628 case PF_HUFFLOOPS: /* HUFFLOOPS */
629 global_huffstruct.loops=
631 global_huffstruct.adjust=1;
634 case PF_HUFFMINS: /* HUFFMINSECONDS */
635 global_huffstruct.request_secs=
639 case PF_DONNET: /* DONNET */
640 tests_to_do[TF_NNET]=getflag(eptr);
643 case PF_NNETLOOPS: /* NNETLOOPS */
644 global_nnetstruct.loops=
646 global_nnetstruct.adjust=1;
649 case PF_NNETMINS: /* NNETMINSECONDS */
650 global_nnetstruct.request_secs=
654 case PF_DOLU: /* DOLU */
655 tests_to_do[TF_LU]=getflag(eptr);
658 case PF_LUNARRAYS: /* LUNUMARRAYS */
659 global_lustruct.numarrays=
661 global_lustruct.adjust=1;
664 case PF_LUMINS: /* LUMINSECONDS */
665 global_lustruct.request_secs=
669 case PF_ALIGN: /* ALIGN */
670 global_align=atoi(eptr);
683 ** Return 1 if cptr points to "T"; 0 otherwise.
685 static int getflag(char *cptr)
687 if(toupper((int)*cptr)=='T') return(1);
694 ** Convert's a string to upper case. The string is presumed
695 ** to consist only of alphabetic characters, and to be terminated
698 static void strtoupper(char *s)
703 ** Oddly enough, the following line did not work under THINK C.
704 ** So, I modified it....hmmmm. --RG
705 *s++=(char)toupper((int)*s);
707 *s=(char)toupper((int)*s);
709 } while(*s!=(char)'\0');
713 /*********************
714 ** set_request_secs **
715 **********************
716 ** Set everyone's "request_secs" entry to whatever
717 ** value is in global_min_secs. This is done
718 ** at the beginning, and possibly later if the
719 ** user redefines global_min_secs in the command file.
721 static void set_request_secs(void)
724 global_numsortstruct.request_secs=global_min_seconds;
725 global_strsortstruct.request_secs=global_min_seconds;
726 global_bitopstruct.request_secs=global_min_seconds;
727 global_emfloatstruct.request_secs=global_min_seconds;
728 global_fourierstruct.request_secs=global_min_seconds;
729 global_assignstruct.request_secs=global_min_seconds;
730 global_ideastruct.request_secs=global_min_seconds;
731 global_huffstruct.request_secs=global_min_seconds;
732 global_nnetstruct.request_secs=global_min_seconds;
733 global_lustruct.request_secs=global_min_seconds;
739 /**************************
740 ** bench_with_confidence **
741 ***************************
742 ** Given a benchmark id that indicates a function, this routine
743 ** repeatedly calls that benchmark, seeking to collect and replace
744 ** scores to get 5 that meet the confidence criteria.
746 ** The above is mathematically questionable, as the statistical theory
747 ** depends on independent observations, and if we exchange data points
748 ** depending on what we already have then this certainly violates
749 ** independence of the observations. Hence I changed this so that at
750 ** most 30 observations are done, but none are deleted as we go
751 ** along. We simply do more runs and hope to get a big enough sample
752 ** size so that things stabilize. Uwe F. Mayer
754 ** Return 0 if ok, -1 if failure. Returns mean
755 ** and std. deviation of results if successful.
757 static int bench_with_confidence(int fid, /* Function id */
758 double *mean, /* Mean of scores */
759 double *stdev, /* Standard deviation */
760 ulong *numtries) /* # of attempts */
762 double myscores[30]; /* Need at least 5 scores, use at most 30 */
763 double c_half_interval; /* Confidence half interval */
765 /* double newscore; */ /* For improving confidence interval */
768 ** Get first 5 scores. Then begin confidence testing.
771 { (*funcpointer[fid])();
772 myscores[i]=getscore(fid);
774 printf("score # %d = %g\n", i, myscores[i]);
777 *numtries=5; /* Show 5 attempts */
780 ** The system allows a maximum of 30 tries before it gives
781 ** up. Since we've done 5 already, we'll allow 25 more.
785 ** Enter loop to test for confidence criteria.
790 ** Calculate confidence. Should always return 0.
792 if (0!=calc_confidence(myscores,
799 ** Is the length of the half interval 5% or less of mean?
800 ** If so, we can go home. Otherwise, we have to continue.
802 if(c_half_interval/ (*mean) <= (double)0.05)
809 /* this code is no longer valid, we now do not replace but add new scores */
812 ** Go get a new score and see if it
813 ** improves existing scores.
818 (*funcpointer[fid])();
820 newscore=getscore(fid);
821 } while(seek_confidence(myscores,&newscore,
822 &c_half_interval,mean,stdev)==0);
824 /* We now simply add a new test run and hope that the runs
825 finally stabilize, Uwe F. Mayer */
826 if(*numtries==30) return(-1);
827 (*funcpointer[fid])();
828 myscores[*numtries]=getscore(fid);
830 printf("score # %ld = %g\n", *numtries, myscores[*numtries]);
839 /* this procecdure is no longer needed, Uwe F. Mayer */
840 /********************
841 ** seek_confidence **
842 *********************
843 ** Pass this routine an array of 5 scores PLUS a new score.
844 ** This routine tries the new score in place of each of
845 ** the other five scores to determine if the new score,
846 ** when replacing one of the others, improves the confidence
848 ** Return 0 if failure. Original 5 scores unchanged.
849 ** Return -1 if success. Also returns new half-interval,
850 ** mean, and standard deviation of the sample.
852 static int seek_confidence( double scores[5],
854 double *c_half_interval,
858 double sdev_to_beat; /* Original sdev to be beaten */
859 double temp; /* For doing a swap */
860 int is_beaten; /* Indicates original was beaten */
864 ** First calculate original standard deviation
866 calc_confidence(scores,c_half_interval,smean,sdev);
871 ** Try to beat original score. We'll come out of this
878 calc_confidence(scores,c_half_interval,smean,sdev);
880 if(sdev_to_beat>*sdev)
887 { scores[is_beaten]=*newscore;
894 /********************
895 ** calc_confidence **
896 *********************
897 ** Given a set of numtries scores, calculate the confidence
898 ** half-interval. We'll also return the sample mean and sample
899 ** standard deviation.
900 ** NOTE: This routines presumes a confidence of 95% and
901 ** a confidence coefficient of .95
902 ** returns 0 if there is an error, otherwise -1
904 static int calc_confidence(double scores[], /* Array of scores */
905 int num_scores, /* number of scores in array */
906 double *c_half_interval, /* Confidence half-int */
907 double *smean, /* Standard mean */
908 double *sdev) /* Sample stand dev */
910 /* Here is a list of the student-t distribution up to 29 degrees of
911 freedom. The value at 0 is bogus, as there is no value for zero
912 degrees of freedom. */
913 double student_t[30]={0.0 , 12.706 , 4.303 , 3.182 , 2.776 , 2.571 ,
914 2.447 , 2.365 , 2.306 , 2.262 , 2.228 ,
915 2.201 , 2.179 , 2.160 , 2.145 , 2.131 ,
916 2.120 , 2.110 , 2.101 , 2.093 , 2.086 ,
917 2.080 , 2.074 , 2.069 , 2.064 , 2.060 ,
918 2.056 , 2.052 , 2.048 , 2.045 };
920 if ((num_scores<2) || (num_scores>30)) {
921 output_string("Internal error: calc_confidence called with an illegal number of scores\n");
925 ** First calculate mean.
928 for(i=0;i<num_scores;i++){
931 *smean/=(double)num_scores;
933 /* Get standard deviation */
935 for(i=0;i<num_scores;i++) {
936 *sdev+=(scores[i]-(*smean))*(scores[i]-(*smean));
938 *sdev/=(double)(num_scores-1);
941 /* Now calculate the length of the confidence half-interval. For a
942 ** confidence level of 95% our confidence coefficient gives us a
943 ** multiplying factor of the upper .025 quartile of a t distribution
944 ** with num_scores-1 degrees of freedom, and dividing by sqrt(number of
945 ** observations). See any introduction to statistics.
947 *c_half_interval=student_t[num_scores-1] * (*sdev) / sqrt((double)num_scores);
954 ** Return the score for a particular benchmark.
956 static double getscore(int fid)
960 ** Fid tells us the function. This is really a matter of
961 ** doing the proper coercion.
966 return(global_numsortstruct.sortspersec);
968 return(global_strsortstruct.sortspersec);
970 return(global_bitopstruct.bitopspersec);
972 return(global_emfloatstruct.emflops);
974 return(global_fourierstruct.fflops);
976 return(global_assignstruct.iterspersec);
978 return(global_ideastruct.iterspersec);
980 return(global_huffstruct.iterspersec);
982 return(global_nnetstruct.iterspersec);
984 return(global_lustruct.iterspersec);
992 ** Displays a string on the screen. Also, if the flag
993 ** write_to_file is set, outputs the string to the output file.
994 ** Note, this routine presumes that you've included a carriage
995 ** return at the end of the buffer.
997 static void output_string(char *buffer)
1000 printf("%s",buffer);
1001 if(write_to_file!=0)
1002 fprintf(global_ofile,"%s",buffer);
1009 ** This routine displays statistics for a particular benchmark.
1010 ** The benchmark is identified by its id.
1012 static void show_stats (int bid)
1014 char buffer[80]; /* Display buffer */
1018 case TF_NUMSORT: /* Numeric sort */
1019 sprintf(buffer," Number of arrays: %d\n",
1020 global_numsortstruct.numarrays);
1021 output_string(buffer);
1022 sprintf(buffer," Array size: %ld\n",
1023 global_numsortstruct.arraysize);
1024 output_string(buffer);
1027 case TF_SSORT: /* String sort */
1028 sprintf(buffer," Number of arrays: %d\n",
1029 global_strsortstruct.numarrays);
1030 output_string(buffer);
1031 sprintf(buffer," Array size: %ld\n",
1032 global_strsortstruct.arraysize);
1033 output_string(buffer);
1036 case TF_BITOP: /* Bitmap operation */
1037 sprintf(buffer," Operations array size: %ld\n",
1038 global_bitopstruct.bitoparraysize);
1039 output_string(buffer);
1040 sprintf(buffer," Bitfield array size: %ld\n",
1041 global_bitopstruct.bitfieldarraysize);
1042 output_string(buffer);
1045 case TF_FPEMU: /* Floating-point emulation */
1046 sprintf(buffer," Number of loops: %lu\n",
1047 global_emfloatstruct.loops);
1048 output_string(buffer);
1049 sprintf(buffer," Array size: %lu\n",
1050 global_emfloatstruct.arraysize);
1051 output_string(buffer);
1054 case TF_FFPU: /* Fourier test */
1055 sprintf(buffer," Number of coefficients: %lu\n",
1056 global_fourierstruct.arraysize);
1057 output_string(buffer);
1061 sprintf(buffer," Number of arrays: %lu\n",
1062 global_assignstruct.numarrays);
1063 output_string(buffer);
1067 sprintf(buffer," Array size: %lu\n",
1068 global_ideastruct.arraysize);
1069 output_string(buffer);
1070 sprintf(buffer," Number of loops: %lu\n",
1071 global_ideastruct.loops);
1072 output_string(buffer);
1076 sprintf(buffer," Array size: %lu\n",
1077 global_huffstruct.arraysize);
1078 output_string(buffer);
1079 sprintf(buffer," Number of loops: %lu\n",
1080 global_huffstruct.loops);
1081 output_string(buffer);
1085 sprintf(buffer," Number of loops: %lu\n",
1086 global_nnetstruct.loops);
1087 output_string(buffer);
1091 sprintf(buffer," Number of arrays: %lu\n",
1092 global_lustruct.numarrays);
1093 output_string(buffer);
1100 ** Following code added for Mac stuff, so that we can emulate command
1109 ** Reads in a command line, and sets up argc and argv appropriately.
1110 ** Note that this routine uses gets() to read in the line. This means
1111 ** you'd better not enter more than 128 characters on a command line, or
1112 ** things will overflow, and oh boy...
1114 void UCommandLine(void)
1116 printf("Enter command line\n:");
1117 gets((char *)Uargbuff);
1125 ** Parse the pseudo command-line. This code appeared as part of the
1126 ** Small-C library in Dr. Dobb's ToolBook of C.
1127 ** It expects the following globals:
1129 ** argv = Pointer to array of char pointers
1130 ** Uargbuff = Character array that holds the arguments. Should be 129 bytes long.
1131 ** Udummy1 = This is a 2-byte buffer that holds a "*", and acts as the first
1132 ** argument in the argument list. This maintains compatibility with other
1133 ** C's, though it does not provide access to the executable filename.
1134 ** This routine allows for up to 20 individual command-line arguments.
1135 ** Also note that this routine does NOT allow for redirection.
1141 argc=0; /* Start arg count */
1142 Udummy[0]='*'; /* Set dummy first argument */
1144 argv[argc++]=(char *)Udummy;
1146 ptr=Uargbuff; /* Start pointer */
1153 if(argc<20) argv[argc++]=(char *)ptr;
1161 ** Isolate the next command-line field.
1163 unsigned char *UField(unsigned char *ptr)
1167 { *ptr=(unsigned char)NULL;