home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / GCC 1.37.1r15 / Tests / Benchmarks / dry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-02  |  11.6 KB  |  535 lines  |  [TEXT/MPS ]

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