home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / bytewarp.zip / NBENCH0.C < prev    next >
C/C++ Source or Header  |  1998-04-13  |  34KB  |  1,054 lines

  1.  
  2. /*
  3. ** nbench0.c
  4. */
  5.  
  6. /*******************************************
  7. **             BYTEmark (tm)              **
  8. ** BYTE MAGAZINE'S NATIVE MODE BENCHMARKS **
  9. **           FOR CPU/FPU                  **
  10. **             ver 2.0                    **
  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.
  15. **
  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
  32. **
  33. ** DISCLAIMER
  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
  45. ** this code.
  46. */
  47.  
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52. #include <time.h>
  53. #include <math.h>
  54. #include "nmglobal.h"
  55. #include "nbench0.h"
  56.  
  57. /*************
  58. **** main ****
  59. *************/
  60. #ifdef MAC
  61. void main(void)
  62. #else
  63. int main(int argc, char *argv[])
  64. #endif
  65. {
  66. int i;                  /* Index */
  67. time_t time_and_date;   /* Self-explanatory */
  68. struct tm *loctime;
  69. double bmean;           /* Benchmark mean */
  70. double bstdev;          /* Benchmark stdev */
  71. double intindex;                /* Integer index */
  72. double fpindex;                 /* Floating-point index */
  73. ulong bnumrun;          /* # of runs */
  74.  
  75. #ifdef MAC
  76.         MaxApplZone();
  77. #endif
  78.                 
  79. #ifdef MACTIMEMGR
  80. /* Set up high res timer */
  81. MacHSTdelay=600*1000*1000;      /* Delay is 10 minutes */
  82.  
  83. memset((char *)&myTMTask,0,sizeof(TMTask));
  84.  
  85. /* Prime and remove the task, calculating overhead */
  86. PrimeTime((QElemPtr)&myTMTask,-MacHSTdelay);
  87. RmvTime((QElemPtr)&myTMTask);
  88. MacHSTohead=MacHSTdelay+myTMTask.tmCount;
  89. #endif
  90.  
  91. #ifdef WIN31TIMER
  92. /* Set up the size of the timer info structure */
  93. win31tinfo.dwSize=(DWORD)sizeof(TIMERINFO);
  94. /* Load library */
  95. if((hThlp=LoadLibrary("TOOLHELP.DLL"))<32)
  96. {       printf("Error loading TOOLHELP\n");
  97.         exit(0);
  98. }
  99. if(!(lpfn=GetProcAddress(hThlp,"TimerCount")))
  100. {       printf("TOOLHELP error\n");
  101.         exit(0);
  102. }
  103. #endif
  104.  
  105. /*
  106. ** Set global parameters to default.
  107. */
  108. global_min_ticks=MINIMUM_TICKS;
  109. global_min_seconds=MINIMUM_SECONDS;
  110. global_allstats=0;
  111. global_custrun=0;
  112. global_align=8;
  113. write_to_file=0;
  114. intindex=(double)1.0;
  115. fpindex=(double)1.0;
  116. mem_array_ents=0;               /* Nothing in mem array */
  117.  
  118. /*
  119. ** We presume all tests will be run unless told
  120. ** otherwise
  121. */
  122. for(i=0;i<NUMTESTS;i++)
  123.         tests_to_do[i]=1;
  124.  
  125. /*
  126. ** Initialize test data structures to default
  127. ** values.
  128. */
  129. set_request_secs();     /* Set all request_secs fields */
  130. global_numsortstruct.adjust=0;
  131. global_numsortstruct.arraysize=NUMARRAYSIZE;
  132.  
  133. global_strsortstruct.adjust=0;
  134. global_strsortstruct.arraysize=STRINGARRAYSIZE;
  135.  
  136. global_bitopstruct.adjust=0;
  137. global_bitopstruct.bitfieldarraysize=BITFARRAYSIZE;
  138.  
  139. global_emfloatstruct.adjust=0;
  140. global_emfloatstruct.arraysize=EMFARRAYSIZE;
  141.  
  142. global_fourierstruct.adjust=0;
  143.  
  144. global_assignstruct.adjust=0;
  145.  
  146. global_ideastruct.adjust=0;
  147. global_ideastruct.arraysize=IDEAARRAYSIZE;
  148.  
  149. global_huffstruct.adjust=0;
  150. global_huffstruct.arraysize=HUFFARRAYSIZE;
  151.  
  152. global_nnetstruct.adjust=0;
  153.  
  154. global_lustruct.adjust=0;
  155.  
  156. /*
  157. ** For Macintosh -- read the command line.
  158. */
  159. #ifdef MAC
  160. UCommandLine();
  161. #endif
  162.  
  163. /*
  164. ** Handle any command-line arguments.
  165. */
  166. if(argc>1)
  167.         for(i=1;i<argc;i++)
  168.                 if(parse_arg(argv[i])==-1)
  169.                 {       display_help(argv[0]);
  170.                         exit(0);
  171.                 }
  172. /*
  173. ** Output header
  174. */
  175. output_string("BBBBBB   YYY   Y  TTTTTTT  EEEEEEE\\     22222222 \n");
  176. output_string("BBB   B  YYY   Y    TTT    EEE     \\    22   222 \n");
  177. output_string("BBB   B  YYY   Y    TTT    EEE      \\       222 \n");
  178. output_string("BBBBBB    YYY Y     TTT    EEEEEEE   \\     222 \n");
  179. output_string("BBB   B    YYY      TTT    EEE        \\   222 \n");
  180. output_string("BBB   B    YYY      TTT    EEE         \\ 222 \n");
  181. output_string("BBBBBB     YYY      TTT    EEEEEEE      \\2222222 \n\n");
  182. output_string("BYTEmark (tm) Native Mode OS/2  Benchmark ver. 2 (10/95)\n");
  183.  
  184. /*
  185. ** See if the user wants all stats.  Output heading info
  186. ** if so.
  187. */
  188. if(global_allstats)
  189. {
  190.                 output_string("========== ALL STATISTICS ==========\n");
  191.         time(&time_and_date);
  192.         loctime=localtime(&time_and_date);
  193.         sprintf(buffer,"**%s",asctime(loctime));
  194.         output_string(buffer);
  195.         sprintf(buffer,"**%s\n",sysname);
  196.         output_string(buffer);
  197.         sprintf(buffer,"**%s\n",compilername);
  198.         output_string(buffer);
  199.         sprintf(buffer,"**%s\n",compilerversion);
  200.         output_string(buffer);
  201.         sprintf(buffer,"**Sizeof: int:%u short:%u long:%u\n",
  202.                 (unsigned int)sizeof(int),
  203.                 (unsigned int)sizeof(short),
  204.                 (unsigned int)sizeof(long));
  205.         output_string(buffer);
  206.                 output_string("====================================\n");
  207. }
  208.  
  209. /*
  210. ** Execute the tests.
  211. */
  212.  
  213. for(i=0;i<NUMTESTS;i++)
  214. {
  215.         if(tests_to_do[i])
  216.         {       sprintf(buffer,"%s:",ftestnames[i]);
  217.                                 output_string(buffer);
  218.                 bench_with_confidence(i,
  219.                         &bmean,
  220.                         &bstdev,
  221.                         &bnumrun);
  222.                 sprintf(buffer,"  Iterations/sec.: %lf  Index: %lf\n",
  223.                         bmean,bmean/bindex[i]);
  224.                 output_string(buffer);
  225.                                 /*
  226.                                 ** Gather integer or FP indexes
  227.                                 */
  228.                                 if((i==4)||(i==8)||(i==9))
  229.                                         /* FP index */
  230.                                         fpindex=fpindex*(bmean/bindex[i]);
  231.                                 else
  232.                                         /* Integer index */
  233.                                         intindex=intindex*(bmean/bindex[i]);
  234.                                         
  235.                 if(global_allstats)
  236.                 {
  237.                         sprintf(buffer,"  Standard Deviation: %lf\n  Number of runs: %lu\n",
  238.                                 bstdev,bnumrun);
  239.                         output_string(buffer);
  240.                         show_stats(i);
  241.                 }
  242.         }
  243. }
  244. printf("...done...\n");
  245.  
  246. /*
  247. ** Output the total indexes
  248. */
  249. if(global_custrun==0)
  250. {
  251.         output_string("===========OVERALL============\n");
  252.         sprintf(buffer,"INTEGER INDEX: %lf\nFLOATING-POINT INDEX: %lf\n",pow(intindex,(double).142857),
  253.                         pow(fpindex,(double).33333));
  254.         output_string(buffer);
  255.         output_string(" (90 MHz Dell Pentium = 1.00)\n");
  256.         output_string("==============================\n");
  257. }
  258.  
  259. exit(0);
  260. }
  261.  
  262. /**************
  263. ** parse_arg **
  264. ***************
  265. ** Given a pointer to a string, we assume that's an argument.
  266. ** Parse that argument and act accordingly.
  267. ** Return 0 if ok, else return -1.
  268. */
  269. static int parse_arg(char *argptr)
  270. {
  271. int i;          /* Index */
  272. FILE *cfile;    /* Command file identifier */
  273.  
  274. /*
  275. ** First character has got to be a hyphen.
  276. */
  277. if(*argptr++!='-') return(-1);
  278.  
  279. /*
  280. ** Convert the rest of the argument to upper case
  281. ** so there's little chance of confusion.
  282. */
  283. for(i=0;i<strlen(argptr);i++)
  284.         argptr[i]=(char)toupper((int)argptr[i]);
  285.  
  286. /*
  287. ** Next character picks the action.
  288. */
  289. switch(*argptr++)
  290. {
  291.         case '?':       return(-1);     /* Will display help */
  292.  
  293.         case 'C':                       /* Command file name */
  294.                 /*
  295.                 ** First try to open the file for reading.
  296.                 */
  297.                 cfile=fopen(argptr,"r");
  298.                 if(cfile==(FILE *)NULL)
  299.                 {       printf("**Error opening file: %s\n",argptr);
  300.                         return(-1);
  301.                 }
  302.                 read_comfile(cfile);    /* Read commands */
  303.                 fclose(cfile);
  304.                 break;
  305.         default:
  306.                 return(-1);
  307. }
  308. return(0);
  309. }
  310.  
  311. /*******************
  312. ** display_help() **
  313. ********************
  314. ** Display a help message showing argument requirements and such.
  315. ** Exit when you're done...I mean, REALLY exit.
  316. */
  317. void display_help(char *progname)
  318. {
  319.         printf("Usage: %s [-c<FILE>]\n",progname);
  320.         printf(" -c = Input parameters thru command file <FILE>\n");
  321.         exit(0);
  322. }
  323.  
  324.  
  325. /*****************
  326. ** read_comfile **
  327. ******************
  328. ** Read the command file.  Set global parameters as
  329. ** specified.  This routine assumes that the command file
  330. ** is already open.
  331. */
  332. static void read_comfile(FILE *cfile)
  333. {
  334. char inbuf[40];
  335. char *eptr;             /* Offset to "=" sign */
  336. int i;                  /* Index */
  337.  
  338. /*
  339. ** Sit in a big loop, reading a line from the file at each
  340. ** pass.  Terminate on EOF.
  341. */
  342. while(fgets(inbuf,39,cfile)!=(char *)NULL)
  343. {
  344.         /* Overwrite the CR character */
  345.         if(strlen(inbuf)>0)
  346.                 inbuf[strlen(inbuf)-1]='\0';
  347.  
  348.         /*
  349.         ** Parse up to the "=" sign.  If we don't find an
  350.         ** "=", then flag an error.
  351.         */
  352.         if((eptr=strchr(inbuf,(int)'='))==(char *)NULL)
  353.         {       printf("**COMMAND FILE ERROR at LINE:\n %s\n",
  354.                         inbuf);
  355.                 goto skipswitch;        /* A GOTO!!!! */
  356.         }
  357.  
  358.         /*
  359.         ** Insert a null where the "=" was, then convert
  360.         ** the substring to uppercase.  That will enable
  361.         ** us to perform the match.
  362.         */
  363.         *eptr++='\0';
  364.         strtoupper((char *)&inbuf[0]);
  365.         i=MAXPARAM;                     
  366.         do {
  367.                 if(strcmp(inbuf,paramnames[i])==0)
  368.                         break;
  369.         } while(--i>=0);
  370.  
  371.         if(i<0)
  372.         {       printf("**COMMAND FILE ERROR -- UNKNOWN PARAM: %s",
  373.                         inbuf);
  374.                 goto skipswitch;
  375.         }
  376.  
  377.         /*
  378.         ** Advance eptr to the next field...which should be
  379.         ** the value assigned to the parameter.
  380.         */
  381.         switch(i)
  382.         {
  383.                 case PF_GMTICKS:        /* GLOBALMINTICKS */
  384.                         global_min_ticks=(ulong)atol(eptr);
  385.                         break;
  386.  
  387.                 case PF_MINSECONDS:     /* MINSECONDS */
  388.                         global_min_seconds=(ulong)atol(eptr);
  389.                         set_request_secs();
  390.                         break;
  391.  
  392.                 case PF_ALLSTATS:       /* ALLSTATS */
  393.                         global_allstats=getflag(eptr);
  394.                         break;
  395.  
  396.                 case PF_OUTFILE:        /* OUTFILE */
  397.                         strcpy(global_ofile_name,eptr);
  398.                         global_ofile=fopen(global_ofile_name,"a");
  399.                         /*
  400.                         ** Open the output file.
  401.                         */
  402.                         if(global_ofile==(FILE *)NULL)
  403.                         {       printf("**Error opening output file: %s\n",
  404.                                         global_ofile_name);
  405.                                 ErrorExit();
  406.                         }
  407.                         write_to_file=-1;
  408.                         break;
  409.  
  410.                 case PF_CUSTOMRUN:      /* CUSTOMRUN */
  411.                         global_custrun=getflag(eptr);
  412.                         for(i=0;i<NUMTESTS;i++)
  413.                                 tests_to_do[i]=1-global_custrun;
  414.                         break;
  415.  
  416.                 case PF_DONUM:          /* DONUMSORT */
  417.                         tests_to_do[TF_NUMSORT]=getflag(eptr);
  418.                         break;
  419.  
  420.                 case PF_NUMNUMA:        /* NUMNUMARRAYS */
  421.                         global_numsortstruct.numarrays=
  422.                                 (ushort)atoi(eptr);
  423.                         global_numsortstruct.adjust=1;
  424.                         break;
  425.  
  426.                 case PF_NUMASIZE:       /* NUMARRAYSIZE */
  427.                         global_numsortstruct.arraysize=
  428.                                 (ulong)atol(eptr);
  429.                         break;
  430.  
  431.                 case PF_NUMMINS:        /* NUMMINSECONDS */
  432.                         global_numsortstruct.request_secs=
  433.                                 (ulong)atol(eptr);
  434.                         break;
  435.  
  436.                 case PF_DOSTR:          /* DOSTRINGSORT */
  437.                         tests_to_do[TF_SSORT]=getflag(eptr);
  438.                         break;
  439.  
  440.                 case PF_STRASIZE:       /* STRARRAYSIZE */
  441.                         global_strsortstruct.arraysize=
  442.                                 (ulong)atol(eptr);
  443.                         break;
  444.  
  445.                 case PF_NUMSTRA:        /* NUMSTRARRAYS */
  446.                         global_strsortstruct.numarrays=
  447.                                 (ushort)atoi(eptr);
  448.                         global_strsortstruct.adjust=1;
  449.                         break;
  450.  
  451.                 case PF_STRMINS:        /* STRMINSECONDS */
  452.                         global_strsortstruct.request_secs=
  453.                                 (ulong)atol(eptr);
  454.                         break;
  455.  
  456.                 case PF_DOBITF: /* DOBITFIELD */
  457.                         tests_to_do[TF_BITOP]=getflag(eptr);
  458.                         break;
  459.  
  460.                 case PF_NUMBITOPS:      /* NUMBITOPS */
  461.                         global_bitopstruct.bitoparraysize=
  462.                                 (ulong)atol(eptr);
  463.                         global_bitopstruct.adjust=1;
  464.                         break;
  465.  
  466.                 case PF_BITFSIZE:       /* BITFIELDSIZE */
  467.                         global_bitopstruct.bitfieldarraysize=
  468.                                 (ulong)atol(eptr);
  469.                         break;
  470.  
  471.                 case PF_BITMINS:        /* BITMINSECONDS */
  472.                         global_bitopstruct.request_secs=
  473.                                 (ulong)atol(eptr);
  474.                         break;
  475.  
  476.                 case PF_DOEMF:          /* DOEMF */
  477.                         tests_to_do[TF_FPEMU]=getflag(eptr);
  478.                         break;
  479.  
  480.                 case PF_EMFASIZE:       /* EMFARRAYSIZE */
  481.                         global_emfloatstruct.arraysize=
  482.                                 (ulong)atol(eptr);
  483.                         break;
  484.  
  485.                 case PF_EMFLOOPS:       /* EMFLOOPS */
  486.                         global_emfloatstruct.loops=
  487.                                 (ulong)atol(eptr);
  488.                         break;
  489.  
  490.                 case PF_EMFMINS:        /* EMFMINSECOND */
  491.                         global_emfloatstruct.request_secs=
  492.                                 (ulong)atol(eptr);
  493.                         break;
  494.  
  495.                 case PF_DOFOUR: /* DOFOUR */
  496.                         tests_to_do[TF_FFPU]=getflag(eptr);
  497.                         break;
  498.  
  499.                 case PF_FOURASIZE:      /* FOURASIZE */
  500.                         global_fourierstruct.arraysize=
  501.                                 (ulong)atol(eptr);
  502.                         global_fourierstruct.adjust=1;
  503.                         break;
  504.  
  505.                 case PF_FOURMINS:       /* FOURMINSECONDS */
  506.                         global_fourierstruct.request_secs=
  507.                                 (ulong)atol(eptr);
  508.                         break;
  509.  
  510.                 case PF_DOASSIGN:       /* DOASSIGN */
  511.                         tests_to_do[TF_ASSIGN]=getflag(eptr);
  512.                         break;
  513.  
  514.                 case PF_AARRAYS:        /* ASSIGNARRAYS */
  515.                         global_assignstruct.numarrays=
  516.                                 (ulong)atol(eptr);
  517.                         break;
  518.  
  519.                 case PF_ASSIGNMINS:     /* ASSIGNMINSECONDS */
  520.                         global_assignstruct.request_secs=
  521.                                 (ulong)atol(eptr);
  522.                         break;
  523.  
  524.                 case PF_DOIDEA: /* DOIDEA */
  525.                         tests_to_do[TF_IDEA]=getflag(eptr);
  526.                         break;
  527.  
  528.                 case PF_IDEAASIZE:      /* IDEAARRAYSIZE */
  529.                         global_ideastruct.arraysize=
  530.                                 (ulong)atol(eptr);
  531.                         break;
  532.  
  533.                 case PF_IDEALOOPS:      /* IDEALOOPS */
  534.                         global_ideastruct.loops=
  535.                                 (ulong)atol(eptr);
  536.                         break;
  537.  
  538.                 case PF_IDEAMINS:       /* IDEAMINSECONDS */
  539.                         global_ideastruct.request_secs=
  540.                                 (ulong)atol(eptr);
  541.                         break;
  542.  
  543.                 case PF_DOHUFF: /* DOHUFF */
  544.                         tests_to_do[TF_HUFF]=getflag(eptr);
  545.                         break;
  546.  
  547.                 case PF_HUFFASIZE:      /* HUFFARRAYSIZE */
  548.                         global_huffstruct.arraysize=
  549.                                 (ulong)atol(eptr);
  550.                         break;
  551.  
  552.                 case PF_HUFFLOOPS:      /* HUFFLOOPS */
  553.                         global_huffstruct.loops=
  554.                                 (ulong)atol(eptr);
  555.                         global_huffstruct.adjust=1;
  556.                         break;
  557.  
  558.                 case PF_HUFFMINS:       /* HUFFMINSECONDS */
  559.                         global_huffstruct.request_secs=
  560.                                 (ulong)atol(eptr);
  561.                         break;
  562.  
  563.                 case PF_DONNET: /* DONNET */
  564.                         tests_to_do[TF_NNET]=getflag(eptr);
  565.                         break;
  566.                     
  567.                 case PF_NNETLOOPS:      /* NNETLOOPS */
  568.                         global_nnetstruct.loops=
  569.                                 (ulong)atol(eptr);
  570.                         global_nnetstruct.adjust=1;
  571.                         break;
  572.  
  573.                 case PF_NNETMINS:       /* NNETMINSECONDS */
  574.                         global_nnetstruct.request_secs=
  575.                                 (ulong)atol(eptr);
  576.                         break;
  577.  
  578.                 case PF_DOLU:           /* DOLU */
  579.                         tests_to_do[TF_LU]=getflag(eptr);
  580.                         break;
  581.  
  582.                 case PF_LUNARRAYS:      /* LUNUMARRAYS */
  583.                         global_lustruct.numarrays=
  584.                                 (ulong)atol(eptr);
  585.                         global_lustruct.adjust=1;
  586.                         break;
  587.  
  588.                 case PF_LUMINS: /* LUMINSECONDS */
  589.                         global_lustruct.request_secs=
  590.                                 (ulong)atol(eptr);
  591.                         break;
  592.  
  593.                                 case PF_ALIGN:          /* ALIGN */
  594.                                                 global_align=atoi(eptr);
  595.                                                 break;
  596.         }
  597. skipswitch:
  598.         continue;
  599. }       /* End while */
  600.  
  601. return;
  602. }
  603.  
  604. /************
  605. ** getflag **
  606. *************
  607. ** Return 1 if cptr points to "T"; 0 otherwise.
  608. */
  609. static int getflag(char *cptr)
  610. {
  611.         if(toupper((int)*cptr)=='T') return(1);
  612. return(0);
  613. }
  614.  
  615. /***************
  616. ** strtoupper **
  617. ****************
  618. ** Convert's a string to upper case.  The string is presumed
  619. ** to consist only of alphabetic characters, and to be terminated
  620. ** with a null.
  621. */
  622. static void strtoupper(char *s)
  623. {
  624.  
  625. do {
  626. /*
  627. ** Oddly enough, the following line did not work under THINK C.
  628. ** So, I modified it....hmmmm. --RG
  629.         *s++=(char)toupper((int)*s);
  630. */
  631.         *s=(char)toupper((int)*s);
  632.         s++;
  633. } while(*s!=(char)'\0');
  634. return;
  635. }
  636.  
  637. /*********************
  638. ** set_request_secs **
  639. **********************
  640. ** Set everyone's "request_secs" entry to whatever
  641. ** value is in global_min_secs.  This is done
  642. ** at the beginning, and possibly later if the
  643. ** user redefines global_min_secs in the command file.
  644. */
  645. static void set_request_secs(void)
  646. {
  647.  
  648. global_numsortstruct.request_secs=global_min_seconds;
  649. global_strsortstruct.request_secs=global_min_seconds;
  650. global_bitopstruct.request_secs=global_min_seconds;
  651. global_emfloatstruct.request_secs=global_min_seconds;
  652. global_fourierstruct.request_secs=global_min_seconds;
  653. global_assignstruct.request_secs=global_min_seconds;
  654. global_ideastruct.request_secs=global_min_seconds;
  655. global_huffstruct.request_secs=global_min_seconds;
  656. global_nnetstruct.request_secs=global_min_seconds;
  657. global_lustruct.request_secs=global_min_seconds;
  658.  
  659. return;
  660. }
  661.  
  662.  
  663. /**************************
  664. ** bench_with_confidence **
  665. ***************************
  666. ** Given a benchmark id that indicates a function, this
  667. ** routine repeatedly calls that benchmark, seeking
  668. ** to collect enough scores to get 5 that meet the confidence
  669. ** criteria.  Return 0 if ok, -1 if failure.
  670. ** Returns mean ans std. deviation of results if successful.
  671. */
  672. static int bench_with_confidence(int fid,       /* Function id */
  673.         double *mean,                   /* Mean of scores */
  674.         double *stdev,                  /* Standard deviation */
  675.         ulong *numtries)                /* # of attempts */
  676. {
  677. double myscores[5];             /* Need at least 5 scores */
  678. double c_half_interval;         /* Confidence half interval */
  679. int i;                          /* Index */
  680. double newscore;                /* For improving confidence interval */
  681.  
  682.  
  683. /*
  684. ** Get first 5 scores.  Then begin confidence testing.
  685. */
  686. for (i=0;i<5;i++)
  687. {       (*funcpointer[fid])();
  688.         myscores[i]=getscore(fid);
  689. }
  690. *numtries=5;            /* Show 5 attempts */
  691.  
  692. /*
  693. ** The system allows a maximum of 10 tries before it gives
  694. ** up.  Since we've done 5 already, we'll allow 5 more.
  695. */
  696.  
  697. /*
  698. ** Enter loop to test for confidence criteria.
  699. */
  700. while(1)
  701. {
  702.         /*
  703.         ** Calculate confidence.
  704.         */
  705.         calc_confidence(myscores,
  706.                 &c_half_interval,
  707.                 mean,
  708.                 stdev);
  709.  
  710.         /*
  711.         ** Is half interval 5% or less of mean?
  712.         ** If so, we can go home.  Otherwise,
  713.         ** we have to continue.
  714.         */
  715.         if(c_half_interval/ (*mean) <= (double)0.05)
  716.                 break;
  717.  
  718.         /*
  719.         ** Go get a new score and see if it
  720.         ** improves existing scores.
  721.         */
  722.         do {
  723.                 if(*numtries==10)
  724.                         return(-1);
  725.                 (*funcpointer[fid])();
  726.                 *numtries+=1;
  727.                 newscore=getscore(fid);
  728.         } while(seek_confidence(myscores,&newscore,
  729.                 &c_half_interval,mean,stdev)==0);
  730. }
  731.  
  732. return(0);
  733. }
  734.  
  735. /********************
  736. ** seek_confidence **
  737. *********************
  738. ** Pass this routine an array of 5 scores PLUS a new score.
  739. ** This routine tries the new score in place of each of
  740. ** the other five scores to determine if the new score,
  741. ** when replacing one of the others, improves the confidence
  742. ** half-interval.
  743. ** Return 0 if failure.  Original 5 scores unchanged.
  744. ** Return -1 if success.  Also returns new half-interval,
  745. ** mean, and stand. dev.
  746. */
  747. static int seek_confidence( double scores[5],
  748.                 double *newscore,
  749.                 double *c_half_interval,
  750.                 double *smean,
  751.                 double *sdev)
  752. {
  753. double sdev_to_beat;    /* Original sdev to be beaten */
  754. double temp;            /* For doing a swap */
  755. int is_beaten;          /* Indicates original was beaten */
  756. int i;                  /* Index */
  757.  
  758. /*
  759. ** First calculate original standard deviation
  760. */
  761. calc_confidence(scores,c_half_interval,smean,sdev);
  762. sdev_to_beat=*sdev;
  763. is_beaten=-1;
  764.  
  765. /*
  766. ** Try to beat original score.  We'll come out of this
  767. ** loop with a flag.
  768. */
  769. for(i=0;i<5;i++)
  770. {
  771.         temp=scores[i];
  772.         scores[i]=*newscore;
  773.         calc_confidence(scores,c_half_interval,smean,sdev);
  774.         scores[i]=temp;
  775.         if(sdev_to_beat>*sdev)
  776.         {       is_beaten=i;
  777.                 sdev_to_beat=*sdev;
  778.         }
  779. }
  780.  
  781. if(is_beaten!=-1)
  782. {       scores[is_beaten]=*newscore;
  783.         return(-1);
  784. }
  785. return(0);
  786. }
  787.  
  788. /********************
  789. ** calc_confidence **
  790. *********************
  791. ** Given a set of 5 scores, calculate the confidence
  792. ** half-interval.  We'l also return the sample mean and sample
  793. ** standard deviation.
  794. ** NOTE: This routines presumes a confidence of 95% and
  795. ** a confidence coefficient of .95
  796. */
  797. static void calc_confidence( double scores[],    /* Array of scores */
  798.                 double *c_half_interval, /* Confidence half-int */
  799.                 double *smean,           /* Standard mean */
  800.                 double *sdev)            /* Sample stand dev */
  801. {
  802. int i;          /* Index */
  803. /*
  804. ** First calculate mean.
  805. */
  806. *smean=(scores[0]+scores[1]+scores[2]+scores[3]+scores[4])/
  807.         (double)5.0;
  808.  
  809. /*
  810. ** Get standard deviation - first get variance
  811. */
  812. *sdev=(double)0.0;
  813. for(i=0;i<5;i++)
  814. {       *sdev+=(scores[i]-(*smean))*(scores[i]-(*smean));
  815. }
  816. *sdev/=(double)4.0;
  817. *sdev=sqrt(*sdev)/sqrt(5.0);
  818.  
  819. /*
  820. ** Now calculate the confidence half-interval.
  821. ** For a confidence level of 95% our confidence coefficient
  822. ** gives us a multiplying factor of 2.776
  823. ** (The upper .025 quartile of a t distribution with 4 degrees
  824. ** of freedom.)
  825. */
  826. *c_half_interval=(double)2.776 * (*sdev);
  827. return;
  828. }
  829.  
  830. /*************
  831. ** getscore **
  832. **************
  833. ** Return the score for a particular benchmark.
  834. */
  835. static double getscore(int fid)
  836. {
  837.  
  838. /*
  839. ** Fid tells us the function.  This is really a matter of
  840. ** doing the proper coercion.
  841. */
  842. switch(fid)
  843. {
  844.         case TF_NUMSORT:
  845.                 return(global_numsortstruct.sortspersec);
  846.         case TF_SSORT:
  847.                 return(global_strsortstruct.sortspersec);
  848.         case TF_BITOP:
  849.                 return(global_bitopstruct.bitopspersec);
  850.         case TF_FPEMU:
  851.                 return(global_emfloatstruct.emflops);
  852.         case TF_FFPU:
  853.                 return(global_fourierstruct.fflops);
  854.         case TF_ASSIGN:
  855.                 return(global_assignstruct.iterspersec);
  856.         case TF_IDEA:
  857.                 return(global_ideastruct.iterspersec);
  858.         case TF_HUFF:
  859.                 return(global_huffstruct.iterspersec);
  860.         case TF_NNET:
  861.                 return(global_nnetstruct.iterspersec);
  862.         case TF_LU:
  863.                 return(global_lustruct.iterspersec);
  864. }
  865. return((double)0.0);
  866. }
  867.  
  868. /******************
  869. ** output_string **
  870. *******************
  871. ** Displays a string on the screen.  Also, if the flag
  872. ** write_to_file is set, outputs the string to the output file.
  873. ** Note, this routine presumes that you've included a carriage
  874. ** return at the end of the buffer.
  875. */
  876. static void output_string(char *buffer)
  877. {
  878.  
  879. printf("%s",buffer);
  880. if(write_to_file!=0)
  881.         fprintf(global_ofile,"%s",buffer);
  882. return;
  883. }
  884.  
  885. /***************
  886. ** show_stats **
  887. ****************
  888. ** This routine displays statistics for a particular benchmark.
  889. ** The benchmark is identified by its id.
  890. */
  891. static void show_stats (int bid)
  892. {
  893. char buffer[80];        /* Display buffer */
  894.  
  895. switch(bid)
  896. {
  897.         case TF_NUMSORT:                /* Numeric sort */
  898.                 sprintf(buffer,"  Number of arrays: %d\n",
  899.                         global_numsortstruct.numarrays);
  900.                 output_string(buffer);
  901.                 sprintf(buffer,"  Array size: %ld\n",
  902.                         global_numsortstruct.arraysize);
  903.                 output_string(buffer);
  904.                 break;
  905.  
  906.         case TF_SSORT:          /* String sort */
  907.                 sprintf(buffer,"  Number of arrays: %d\n",
  908.                         global_strsortstruct.numarrays);
  909.                 output_string(buffer);
  910.                 sprintf(buffer,"  Array size: %ld\n",
  911.                         global_strsortstruct.arraysize);
  912.                 output_string(buffer);
  913.                 break;
  914.  
  915.         case TF_BITOP:          /* Bitmap operation */
  916.                 sprintf(buffer,"  Operations array size: %ld\n",
  917.                         global_bitopstruct.bitoparraysize);
  918.                 output_string(buffer);
  919.                 sprintf(buffer,"  Bitfield array size: %ld\n",
  920.                         global_bitopstruct.bitfieldarraysize);
  921.                 output_string(buffer);
  922.                 break;
  923.  
  924.         case TF_FPEMU:          /* Floating-point emulation */
  925.                 sprintf(buffer,"  Number of loops: %lu\n",
  926.                         global_emfloatstruct.loops);
  927.                 output_string(buffer);
  928.                 sprintf(buffer,"  Array size: %lu\n",
  929.                         global_emfloatstruct.arraysize);
  930.                 output_string(buffer);
  931.                 break;
  932.  
  933.         case TF_FFPU:           /* Fourier test */
  934.                 sprintf(buffer,"  Number of coefficients: %lu\n",
  935.                         global_fourierstruct.arraysize);
  936.                 output_string(buffer);
  937.                 break;
  938.  
  939.         case TF_ASSIGN:
  940.                 sprintf(buffer,"  Number of arrays: %lu\n",
  941.                         global_assignstruct.numarrays);
  942.                 output_string(buffer);
  943.                 break;
  944.  
  945.         case TF_IDEA:
  946.                 sprintf(buffer,"  Array size: %lu\n",
  947.                         global_ideastruct.arraysize);
  948.                 output_string(buffer);
  949.                 sprintf(buffer," Number of loops: %lu\n",
  950.                         global_ideastruct.loops);
  951.                 output_string(buffer);
  952.                 break;
  953.  
  954.         case TF_HUFF:
  955.                 sprintf(buffer,"  Array size: %lu\n",
  956.                         global_huffstruct.arraysize);
  957.                 output_string(buffer);
  958.                 sprintf(buffer,"  Number of loops: %lu\n",
  959.                         global_huffstruct.loops);
  960.                 output_string(buffer);
  961.                 break;
  962.  
  963.         case TF_NNET:
  964.                 sprintf(buffer,"  Number of loops: %lu\n",
  965.                         global_nnetstruct.loops);
  966.                 output_string(buffer);
  967.                 break;
  968.  
  969.         case TF_LU:
  970.                 sprintf(buffer,"  Number of arrays: %lu\n",
  971.                         global_lustruct.numarrays);
  972.                 output_string(buffer);
  973.                 break;
  974. }
  975. return;
  976. }
  977.  
  978. /*
  979. ** Following code added for Mac stuff, so that we can emulate command
  980. ** lines.
  981. */
  982.  
  983. #ifdef MAC
  984.  
  985. /*****************
  986. ** UCommandLine **
  987. ******************
  988. ** Reads in a command line, and sets up argc and argv appropriately.
  989. ** Note that this routine uses gets() to read in the line.  This means
  990. ** you'd better not enter more than 128 characters on a command line, or
  991. ** things will overflow, and oh boy...
  992. */
  993. void UCommandLine(void)
  994. {
  995. printf("Enter command line\n:");
  996. gets((char *)Uargbuff);
  997. UParse();
  998. return;
  999. }
  1000.  
  1001. /***********
  1002. ** UParse **
  1003. ************
  1004. ** Parse the pseudo command-line.  This code appeared as part of the
  1005. ** Small-C library in Dr. Dobb's ToolBook of C.
  1006. ** It expects the following globals:
  1007. ** argc = arg count
  1008. ** argv = Pointer to array of char pointers
  1009. ** Uargbuff = Character array that holds the arguments.  Should be 129 bytes long.
  1010. ** Udummy1 = This is a 2-byte buffer that holds a "*", and acts as the first
  1011. **  argument in the argument list.  This maintains compatibility with other
  1012. **  C's, though it does not provide access to the executable filename.
  1013. ** This routine allows for up to 20 individual command-line arguments.
  1014. ** Also note that this routine does NOT allow for redirection.
  1015. */
  1016. void UParse(void)
  1017. {
  1018. unsigned char *ptr;
  1019.  
  1020. argc=0;         /* Start arg count */
  1021. Udummy[0]='*';  /* Set dummy first argument */
  1022. Udummy[1]='\0';
  1023. argv[argc++]=(char *)Udummy;
  1024.  
  1025. ptr=Uargbuff;           /* Start pointer */
  1026. while(*ptr)
  1027. {
  1028.         if(isspace(*ptr))
  1029.         {       ++ptr;
  1030.                 continue;
  1031.         }
  1032.         if(argc<20) argv[argc++]=(char *)ptr;
  1033.         ptr=UField(ptr);
  1034. }
  1035. return;
  1036. }
  1037. /***********
  1038. ** UField **
  1039. ************
  1040. ** Isolate the next command-line field.
  1041. */
  1042. unsigned char *UField(unsigned char *ptr)
  1043. {
  1044. while(*ptr)
  1045. {       if(isspace(*ptr))
  1046.         {       *ptr=(unsigned char)NULL;
  1047.                 return(++ptr);
  1048.         }
  1049.         ++ptr;
  1050. }
  1051. return(ptr);
  1052. }
  1053. #endif
  1054.