home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / OS2MNX1.ZIP / DHRYSTON.C < prev    next >
C/C++ Source or Header  |  1989-12-25  |  13KB  |  562 lines

  1. /* dhrystone - benchmark program */
  2.  
  3. /* $Header: D:/RCS/RCS/dhryston.c 1.1 89/12/09 04:42:57 RCA Exp $
  4.  * $Log:    dhryston.c $
  5.  * Revision 1.1  89/12/09  04:42:57  RCA
  6.  * Initial revision
  7.  * 
  8.  * Compile in small memory model with optimization
  9.  */
  10.  
  11. /* Prototypes for functions defined in dhryston.c */
  12. int __near main(void);
  13. int __near Proc0(void);
  14. /* int __near Proc1(struct Record *); */
  15. int __near Proc2(int *);
  16. /* int __near Proc3(struct Record **); */
  17. int __near Proc4(void);
  18. int __near Proc5(void);
  19. int __near Proc6(int,
  20.               int *);
  21. int __near Proc7(int,
  22.               int,
  23.               int *);
  24. int __near Proc8(int *,
  25.               int (*)[],
  26.               int,
  27.               int);
  28. /* int __near Func1(int,
  29.  *             int);
  30.  */
  31. int __near Func2(char *,
  32.               char *);
  33. int __near Func3(int);
  34. /* int __near memcpy(register char *,
  35.  *              register char *,
  36.  *              register int);
  37.  * ter char __far *,
  38.  *             register int);
  39.  */
  40.  
  41. #define REGISTER
  42. /*
  43.  *
  44.  *    "DHRYSTONE" Benchmark Program
  45.  *
  46.  *    Version:    C/1.1, 12/01/84
  47.  *
  48.  *    Date:        PROGRAM updated 01/06/86, COMMENTS changed 01/31/87
  49.  *
  50.  *    Author:        Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg.1013
  51.  *            Translated from ADA by Rick Richardson
  52.  *            Every method to preserve ADA-likeness has been used,
  53.  *            at the expense of C-ness.
  54.  *
  55.  *    Compile:    cc -O dry.c -o drynr            : No registers
  56.  *            cc -O -DREG=register dry.c -o dryr    : Registers
  57.  *
  58.  *    Defines:    Defines are provided for old C compiler's
  59.  *            which don't have enums, and can't assign structures.
  60.  *            The time(2) function is library dependant; Most
  61.  *            return the time in seconds, but beware of some, like
  62.  *            Aztec C, which return other units.
  63.  *            The LOOPS define is initially set for 50000 loops.
  64.  *            If you have a machine with large integers and is
  65.  *            very fast, please change this number to 500000 to
  66.  *            get better accuracy.  Please select the way to
  67.  *            measure the execution time using the TIME define.
  68.  *            For single user machines, time(2) is adequate. For
  69.  *            multi-user machines where you cannot get single-user
  70.  *            access, use the times(2) function.  Be careful to
  71.  *            adjust the HZ parameter below for the units which
  72.  *            are returned by your times(2) function.  You can
  73.  *            sometimes find this in <sys/param.h>.  If you have
  74.  *            neither time(2) nor times(2), use a stopwatch in
  75.  *            the dead of the night.
  76.  *            Use a "printf" at the point marked "start timer"
  77.  *            to begin your timings. DO NOT use the UNIX "time(1)"
  78.  *            command, as this will measure the total time to
  79.  *            run this program, which will (erroneously) include
  80.  *            the time to malloc(3) storage and to compute the
  81.  *            time it takes to do nothing.
  82.  *
  83.  *    Run:        drynr; dryr
  84.  *
  85.  *    Results:    If you get any new machine/OS results, please send to:
  86.  *
  87.  *                ihnp4!castor!pcrat!rick
  88.  *
  89.  *            and thanks to all that do.
  90.  *
  91.  *    Note:        I order the list in increasing performance of the
  92.  *            "with registers" benchmark.  If the compiler doesn't
  93.  *            provide register variables, then the benchmark
  94.  *            is the same for both REG and NOREG.
  95.  *
  96.  *    PLEASE:        Send complete information about the machine type,
  97.  *            clock speed, OS and C manufacturer/version.  If
  98.  *            the machine is modified, tell me what was done.
  99.  *            On UNIX, execute uname -a and cc -V to get this info.
  100.  *
  101.  *    80x8x NOTE:    80x8x benchers: please try to do all memory models
  102.  *            for a particular compiler.
  103.  *
  104.  *
  105.  *    The following program contains statements of a high-level programming
  106.  *    language (C) in a distribution considered representative:
  107.  *
  108.  *    assignments            53%
  109.  *    control statements        32%
  110.  *    procedure, function calls    15%
  111.  *
  112.  *    100 statements are dynamically executed.  The program is balanced with
  113.  *    respect to the three aspects:
  114.  *        - statement type
  115.  *        - operand type (for simple data types)
  116.  *        - operand access
  117.  *            operand global, local, parameter, or constant.
  118.  *
  119.  *    The combination of these three aspects is balanced only approximately.
  120.  *
  121.  *    The program does not compute anything meaningfull, but it is
  122.  *    syntactically and semantically correct.
  123.  *
  124.  */
  125.  
  126.  
  127. /* Accuracy of timings and human fatigue controlled by next two lines */
  128. #define LOOPS    50000        /* Use this for slow or 16 bit machines */
  129. /*#define LOOPS    500000        /* Use this for faster machines */
  130.  
  131.  
  132. /* Compiler dependent options */
  133. #define    NOENUM            /* Define if compiler has no enum's */
  134. #define    NOSTRUCTASSIGN        /* Define if compiler can't assign structures */
  135.  
  136.  
  137. /* Define only one of the next two defines */
  138. /*#define TIMES            /* Use times(2) time function */
  139. #define TIME            /* Use time(2) time function */
  140.  
  141.  
  142. /* Define the granularity of your times(2) function (when used) */
  143. /*#define HZ    50        /* times(2) returns 1/50 second (europe?) */
  144. #define HZ    60        /* times(2) returns 1/60 second (most) */
  145. /*#define HZ    100        /* times(2) returns 1/100 second (WECo) */
  146.  
  147.  
  148. /* For compatibility with goofed up version */
  149. /*#undef GOOF            /* Define if you want the goofed up version */
  150.  
  151.  
  152. #ifdef GOOF
  153. char Version[] = "1.0";
  154. #else
  155. char Version[] = "1.1";
  156. #endif
  157.  
  158.  
  159. #ifdef    NOSTRUCTASSIGN
  160. #define    structassign(d, s)    memcpy(&(d), &(s), sizeof(d))
  161. #else
  162. #define    structassign(d, s)    d = s
  163. #endif
  164.  
  165.  
  166. #ifdef    NOENUM
  167. #define    Ident1    1
  168. #define    Ident2    2
  169. #define    Ident3    3
  170. #define    Ident4    4
  171. #define    Ident5    5
  172. typedef int Enumeration;
  173. #else
  174. typedef enum {
  175.   Ident1, Ident2, Ident3, Ident4, Ident5
  176. } Enumeration;
  177.  
  178. #endif
  179.  
  180.  
  181. typedef int OneToThirty;
  182. typedef int OneToFifty;
  183. typedef char CapitalLetter;
  184. typedef char String30[31];
  185. typedef int Array1Dim[51];
  186. typedef int Array2Dim[51][51];
  187.  
  188.  
  189. struct Record {
  190.   struct Record *PtrComp;
  191.   Enumeration Discr;
  192.   Enumeration EnumComp;
  193.   OneToFifty IntComp;
  194.   String30 StringComp;
  195. };
  196.  
  197.  
  198. typedef struct Record RecordType;
  199. typedef RecordType *RecordPtr;
  200. typedef int boolean;
  201.  
  202.  
  203. #define    NULL        0
  204. #define    TRUE        1
  205. #define    FALSE        0
  206.  
  207.  
  208. #ifndef REG
  209. #define    REG
  210. #endif
  211.  
  212.  
  213. extern Enumeration Func1();
  214. extern boolean Func2();
  215.  
  216.  
  217. #ifdef TIMES
  218. #include <sys/types.h>
  219. #include <sys/times.h>
  220. #endif
  221.  
  222.  
  223. main(void)
  224. {
  225.   printf("\nWait 1 minute...\n");
  226.   Proc0();
  227.   exit(0);
  228. }
  229.  
  230.  
  231. /* Package 1  */
  232. int IntGlob;
  233. boolean BoolGlob;
  234. char Char1Glob;
  235. char Char2Glob;
  236. Array1Dim Array1Glob;
  237. Array2Dim Array2Glob;
  238. RecordPtr PtrGlb;
  239. RecordPtr PtrGlbNext;
  240.  
  241.  
  242. Proc0(void)
  243. {
  244.   OneToFifty IntLoc1;
  245.   REG OneToFifty IntLoc2;
  246.   OneToFifty IntLoc3;
  247. /* RCA unreferenced
  248.  *  REG char CharLoc;
  249.  */
  250.   REG char CharIndex;
  251.   Enumeration EnumLoc;
  252.   String30 String1Loc;
  253.   String30 String2Loc;
  254.   extern char *malloc();
  255.   register unsigned int i;
  256.  
  257.  
  258. #ifdef TIME
  259.   long time();
  260.   long starttime;
  261.   long benchtime;
  262.   long nulltime;
  263.  
  264.  
  265.   starttime = time((long *) 0);
  266.   for (i = 0; i < LOOPS; ++i);
  267.   nulltime = time((long *) 0) - starttime;    /* Computes o'head of loop */
  268. #endif
  269.  
  270. #ifdef TIMES
  271.   time_t starttime;
  272.   time_t benchtime;
  273.   time_t nulltime;
  274.   struct tms tms;
  275.  
  276.  
  277.   times(&tms);
  278.   starttime = tms.tms_utime;
  279.   for (i = 0; i < LOOPS; ++i);
  280.   times(&tms);
  281.   nulltime = tms.tms_utime - starttime;    /* Computes overhead of looping */
  282. #endif
  283.  
  284.  
  285.   PtrGlbNext = (RecordPtr) malloc(sizeof(RecordType));
  286.   PtrGlb = (RecordPtr) malloc(sizeof(RecordType));
  287.   PtrGlb->PtrComp = PtrGlbNext;
  288.   PtrGlb->Discr = Ident1;
  289.   PtrGlb->EnumComp = Ident3;
  290.   PtrGlb->IntComp = 40;
  291.   strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM, SOME STRING");
  292. #ifndef    GOOF
  293.   strcpy(String1Loc, "DHRYSTONE PROGRAM, 1'ST STRING");    /* GOOF */
  294. #endif
  295.  
  296.   Array2Glob[8][7] = 10;    /* Was missing in published program */
  297.  
  298.  
  299. /*****************
  300. -- Start Timer --
  301. *****************/
  302. #ifdef TIME
  303.   starttime = time((long *) 0);
  304. #endif
  305.  
  306. #ifdef TIMES
  307.   times(&tms);
  308.   starttime = tms.tms_utime;
  309. #endif
  310.  
  311.   for (i = 0; i < LOOPS; ++i) {
  312.     Proc5();
  313.     Proc4();
  314.     IntLoc1 = 2;
  315.     IntLoc2 = 3;
  316.     strcpy(String2Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
  317.     EnumLoc = Ident2;
  318.     BoolGlob = !Func2(String1Loc, String2Loc);
  319.     while (IntLoc1 < IntLoc2) {
  320.         IntLoc3 = 5 * IntLoc1 - IntLoc2;
  321.         Proc7(IntLoc1, IntLoc2, &IntLoc3);
  322.         ++IntLoc1;
  323.     }
  324.     Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
  325.     Proc1(PtrGlb);
  326.     for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex)
  327.         if (EnumLoc == Func1(CharIndex, 'C'))
  328.             Proc6(Ident1, &EnumLoc);
  329.     IntLoc3 = IntLoc2 * IntLoc1;
  330.     IntLoc2 = IntLoc3 / IntLoc1;
  331.     IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1;
  332.     Proc2(&IntLoc1);
  333.   }
  334.  
  335.  
  336. /*****************
  337. -- Stop Timer --
  338. *****************/
  339.  
  340.  
  341. #ifdef TIME
  342.   benchtime = time((long *) 0) - starttime - nulltime;
  343.   printf("Dhrystone(%s) time for %ld passes = %ld\n",
  344.          Version,
  345.          (long) LOOPS, benchtime);
  346.   printf("This machine benchmarks at %ld dhrystones/second\n",
  347.          ((long) LOOPS) / benchtime);
  348. #endif
  349.  
  350. #ifdef TIMES
  351.   times(&tms);
  352.   benchtime = tms.tms_utime - starttime - nulltime;
  353.   printf("Dhrystone(%s) time for %ld passes = %ld\n",
  354.          Version,
  355.          (long) LOOPS, benchtime / HZ);
  356.   printf("This machine benchmarks at %ld dhrystones/second\n",
  357.          ((long) LOOPS) * HZ / benchtime);
  358. #endif
  359.  
  360.  
  361. }
  362.  
  363.  
  364. Proc1(PtrParIn)
  365. REG RecordPtr PtrParIn;
  366. {
  367. #define    NextRecord    (*(PtrParIn->PtrComp))
  368.  
  369.  
  370.   structassign(NextRecord, *PtrGlb);
  371.   PtrParIn->IntComp = 5;
  372.   NextRecord.IntComp = PtrParIn->IntComp;
  373.   NextRecord.PtrComp = PtrParIn->PtrComp;
  374.   Proc3(NextRecord.PtrComp);
  375.   if (NextRecord.Discr == Ident1) {
  376.     NextRecord.IntComp = 6;
  377.     Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp);
  378.     NextRecord.PtrComp = PtrGlb->PtrComp;
  379.     Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp);
  380.   } else
  381.     structassign(*PtrParIn, NextRecord);
  382.  
  383.  
  384. #undef    NextRecord
  385. }
  386.  
  387.  
  388. Proc2(IntParIO)
  389. OneToFifty *IntParIO;
  390. {
  391.   REG OneToFifty IntLoc;
  392.   REG Enumeration EnumLoc;
  393.  
  394.  
  395.   IntLoc = *IntParIO + 10;
  396.   for (;;) {
  397.     if (Char1Glob == 'A') {
  398.         --IntLoc;
  399.         *IntParIO = IntLoc - IntGlob;
  400.         EnumLoc = Ident1;
  401.     }
  402.     if (EnumLoc == Ident1) break;
  403.   }
  404. }
  405.  
  406.  
  407. Proc3(PtrParOut)
  408. RecordPtr *PtrParOut;
  409. {
  410.   if (PtrGlb != NULL)
  411.     *PtrParOut = PtrGlb->PtrComp;
  412.   else
  413.     IntGlob = 100;
  414.   Proc7(10, IntGlob, &PtrGlb->IntComp);
  415. }
  416.  
  417.  
  418. Proc4(void)
  419. {
  420.   REG boolean BoolLoc;
  421.  
  422.  
  423.   BoolLoc = Char1Glob == 'A';
  424.   BoolLoc |= BoolGlob;
  425.   Char2Glob = 'B';
  426. }
  427.  
  428.  
  429. Proc5(void)
  430. {
  431.   Char1Glob = 'A';
  432.   BoolGlob = FALSE;
  433. }
  434.  
  435.  
  436. extern boolean Func3();
  437.  
  438.  
  439. Proc6(EnumParIn, EnumParOut)
  440. REG Enumeration EnumParIn;
  441. REG Enumeration *EnumParOut;
  442. {
  443.   *EnumParOut = EnumParIn;
  444.   if (!Func3(EnumParIn)) *EnumParOut = Ident4;
  445.   switch (EnumParIn) {
  446.       case Ident1:    *EnumParOut = Ident1;    break;
  447.       case Ident2:
  448.     if (IntGlob > 100)
  449.         *EnumParOut = Ident1;
  450.     else
  451.         *EnumParOut = Ident4;
  452.     break;
  453.       case Ident3:    *EnumParOut = Ident2;    break;
  454.       case Ident4:
  455.     break;
  456.       case Ident5:    *EnumParOut = Ident3;
  457. }
  458. }
  459.  
  460.  
  461. Proc7(IntParI1, IntParI2, IntParOut)
  462. OneToFifty IntParI1;
  463. OneToFifty IntParI2;
  464. OneToFifty *IntParOut;
  465. {
  466.   REG OneToFifty IntLoc;
  467.  
  468.  
  469.   IntLoc = IntParI1 + 2;
  470.   *IntParOut = IntParI2 + IntLoc;
  471. }
  472.  
  473.  
  474. Proc8(Array1Par, Array2Par, IntParI1, IntParI2)
  475. Array1Dim Array1Par;
  476. Array2Dim Array2Par;
  477. OneToFifty IntParI1;
  478. OneToFifty IntParI2;
  479. {
  480.   REG OneToFifty IntLoc;
  481.   REG OneToFifty IntIndex;
  482.  
  483.  
  484.   IntLoc = IntParI1 + 5;
  485.   Array1Par[IntLoc] = IntParI2;
  486.   Array1Par[IntLoc + 1] = Array1Par[IntLoc];
  487.   Array1Par[IntLoc + 30] = IntLoc;
  488.   for (IntIndex = IntLoc; IntIndex <= (IntLoc + 1); ++IntIndex)
  489.     Array2Par[IntLoc][IntIndex] = IntLoc;
  490.   ++Array2Par[IntLoc][IntLoc - 1];
  491.   Array2Par[IntLoc + 20][IntLoc] = Array1Par[IntLoc];
  492.   IntGlob = 5;
  493. }
  494.  
  495.  
  496. Enumeration Func1(CharPar1, CharPar2)
  497. CapitalLetter CharPar1;
  498. CapitalLetter CharPar2;
  499. {
  500.   REG CapitalLetter CharLoc1;
  501.   REG CapitalLetter CharLoc2;
  502.  
  503.  
  504.   CharLoc1 = CharPar1;
  505.   CharLoc2 = CharLoc1;
  506.   if (CharLoc2 != CharPar2)
  507.     return(Ident1);
  508.   else
  509.     return(Ident2);
  510. }
  511.  
  512.  
  513. boolean Func2(StrParI1, StrParI2)
  514. String30 StrParI1;
  515. String30 StrParI2;
  516. {
  517.   REG OneToThirty IntLoc;
  518.   REG CapitalLetter CharLoc;
  519.  
  520.  
  521.   IntLoc = 1;
  522.   while (IntLoc <= 1)
  523.     if (Func1(StrParI1[IntLoc], StrParI2[IntLoc + 1]) == Ident1) {
  524.         CharLoc = 'A';
  525.         ++IntLoc;
  526.     }
  527.   if (CharLoc >= 'W' && CharLoc <= 'Z') IntLoc = 7;
  528.   if (CharLoc == 'X')
  529.     return(TRUE);
  530.   else {
  531.     if (strcmp(StrParI1, StrParI2) > 0) {
  532.         IntLoc += 7;
  533.         return(TRUE);
  534.     } else
  535.         return(FALSE);
  536.   }
  537. }
  538.  
  539.  
  540. boolean Func3(EnumParIn)
  541. REG Enumeration EnumParIn;
  542. {
  543.   REG Enumeration EnumLoc;
  544.  
  545.  
  546.   EnumLoc = EnumParIn;
  547.   if (EnumLoc == Ident3) return(TRUE);
  548.   return(FALSE);
  549. }
  550.  
  551.  
  552. #ifdef    NOSTRUCTASSIGN
  553. memcpy(d, s, l)
  554. register char *d;
  555. register char *s;
  556. register int l;
  557. {
  558.   while (l--) *d++ = *s++;
  559. }
  560.  
  561. #endif
  562.