home *** CD-ROM | disk | FTP | other *** search
/ PC-Test Pro / PCTESTPRO.iso / benchmrk / dstone / entp / dhry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-04  |  11.1 KB  |  409 lines

  1. /*
  2.  *    "DHRYSTONE" Benchmark Program
  3.  *
  4.  *    Version:    C/1.1, 
  5.  *
  6.  *    Date:        PROGRAM updated 02 Feb 95, RESULTS updated 03/31/86
  7.  *
  8.  *    Author:        Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg. 1013
  9.  *            Translated from ADA by Rick Richardson.
  10.  *            Translated from C to ANSI C by James Day.
  11.  *
  12.  *    ANSI notes:    I corrected a bug where the Loop counter was an int which on 16
  13.  *            bit machines caused an infinite loop where more than UINT_MAX
  14.  *            (62768) loops were used. The one second clock resolution was not
  15.  *            high enough to measure the loop overhead so I both converted the
  16.  *            program to use the ANSI clock routine which has finer resolution
  17.  *            and ensured that the empty loop takes a measurable number
  18.  *            of clock ticks to execute. This is the calibration phase
  19.  *            that the program mentions at the start.
  20.  *            The core of the benchmark loop wasn't touched in the conversion.
  21.  *
  22.  *    Note:        I order the list in increasing performance of the
  23.  *            "with registers" benchmark.  If the compiler doesn't
  24.  *            provide register variables, then the benchmark
  25.  *            is the same for both REG and NOREG.
  26.  *
  27.  *    Warning:    This code is highly susceptible to optimisation. You MUST
  28.  *            disable all significant loop optimisation and function call
  29.  *            inlining to get a meaningful result. Turning on all Microsoft
  30.  *            compiler options doubled the score compared to just using automatic
  31.  *            register assignment.
  32.  *
  33.  * RESULTS BEGIN HERE
  34.  *
  35.  *----------------DHRYSTONE VERSION 1.1 RESULTS BEGIN--------------------------
  36.  *
  37.  * MACHINE    MICROPROCESSOR    OPERATING    COMPILER    DHRYSTONES/SEC.
  38.  * TYPE                SYSTEM                NO REG    REGS
  39.  * --------------------------    ------------    -----------    ---------------
  40.  * Apple IIe    65C02-1.02Mhz    DOS 3.3        Aztec CII v1.05i  37      37
  41.  * -        Z80-2.5Mhz    CPM-80 v2.2    Aztec CII v1.05g  91      91
  42.  * -        8086-8Mhz    RMX86 V6    Intel C-86 V2.0     197     203LM??
  43.  * IBM PC/XT    8088-4.77Mhz    COHERENT 2.3.43    Mark Wiiliams     259     275
  44.  * -        8086-8Mhz    RMX86 V6    Intel C-86 V2.0     287     304 ??
  45.  * Fortune 32:16 68000-6Mhz    V7+sys3+4.1BSD  cc         360     346
  46.  * PDP-11/34A    w/FP-11C    UNIX V7m    cc         406     449
  47.  * Macintosh512    68000-7.7Mhz    Mac ROM O/S    DeSmet(C ware)     625     625
  48.  * VAX-11/750    w/FPA        UNIX 4.2BSD    cc         831     852
  49.  * DataMedia 932 68000-10Mhz    UNIX sysV    cc         837     888
  50.  * Plexus P35    68000-12.5Mhz    UNIX sysIII    cc         835     894
  51.  * ATT PC7300    68010-10Mhz    UNIX 5.0.3    cc         973    1034
  52.  * Compaq II    80286-8Mhz    MSDOS 3.1    MS C 3.0     1086    1140 LM
  53.  * IBM PC/AT    80286-7.5Mhz    Venix/286 SVR2  cc              1159    1254 *15
  54.  * Compaq II    80286-8Mhz    MSDOS 3.1    MS C 3.0     1190    1282 MM
  55.  * MicroVAX II    -        Mach/4.3    cc        1361    1385
  56.  * DEC uVAX II    -        Ultrix-32m v1.1    cc        1385    1399
  57.  * Compaq II    80286-8Mhz    MSDOS 3.1    MS C 3.0     1351    1428
  58.  * VAX 11/780    -        UNIX 4.2BSD    cc        1417    1441
  59.  * VAX-780/MA780        Mach/4.3    cc        1428    1470
  60.  * VAX 11/780    -        UNIX 5.0.1    cc 4.1.1.31    1650    1640
  61.  * Ridge 32C V1    -        ROS 3.3        Ridge C (older)    1628    1695
  62.  * Gould PN6005    -        UTX 1.1c+ (4.2)    cc        1732    1884
  63.  * Gould PN9080    custom ECL    UTX-32 1.1C    cc        4745    4992
  64.  * VAX-784    -        Mach/4.3    cc        5263    5555 &4
  65.  * VAX 8600    -        4.3 BSD        cc        6329    6423
  66.  * Amdahl 5860    -        UTS sysV    cc 1.22           28735   28846
  67.  * IBM3090/200    -        ?        ?           31250   31250
  68.  *
  69.  * NOTE
  70.  *   *   Crystal changed from 'stock' to listed value.
  71.  *   LM  Large Memory Model. (Otherwise, all 80x8x results are small model)
  72.  *   MM  Medium Memory Model. (Otherwise, all 80x8x results are small model)
  73.  *   &nn This machine has "nn" processors, and the benchmark results were
  74.  *     obtained by having all "nn" processors working on 1 copy of dhrystone.
  75.  *     (Note, this is different than Nnn. Salesmen like this measure).
  76.  *   ?   I don't trust results marked with '?'.  These were sent to me with
  77.  *       either incomplete info, or with times that just don't make sense.
  78.  *     ?? means I think the performance is too poor, ?! means too good.
  79.  *       If anybody can confirm these figures, please respond.
  80.  *
  81.  *  ABBREVIATIONS
  82.  *    CCC    Concurrent Computer Corp. (was Perkin-Elmer)
  83.  *    MC    Masscomp
  84.  *
  85.  *--------------------------------RESULTS END----------------------------------
  86.  *
  87.  *    The following program contains statements of a high-level programming
  88.  *    language (C) in a distribution considered representative:
  89.  *
  90.  *    assignments            53%
  91.  *    control statements        32%
  92.  *    procedure, function calls    15%
  93.  *
  94.  *    100 statements are dynamically executed.  The program is balanced with
  95.  *    respect to the three aspects:
  96.  *        - statement type
  97.  *        - operand type (for simple data types)
  98.  *        - operand access
  99.  *            operand global, local, parameter, or constant.
  100.  *
  101.  *    The combination of these three aspects is balanced only approximately.
  102.  *
  103.  *    The program does not compute anything meaningfull, but it is
  104.  *    syntactically and semantically correct.
  105.  *
  106.  */
  107.  
  108. /* Next line sets the initial calibration loop count only. */
  109. #define LOOPS    10000
  110.  
  111. char    Version[] = "1.1";
  112.  
  113. #define    structassign(d, s)    d = s
  114.  
  115. typedef enum    {Ident1, Ident2, Ident3, Ident4, Ident5} Enumeration;
  116.  
  117. typedef int    OneToThirty;
  118. typedef int    OneToFifty;
  119. typedef char    CapitalLetter;
  120. typedef char    String30[31];
  121. typedef int    Array1Dim[51];
  122. typedef int    Array2Dim[51][51];
  123.  
  124. struct    Record
  125. {
  126.     struct Record        *PtrComp;
  127.     Enumeration        Discr;
  128.     Enumeration        EnumComp;
  129.     OneToFifty        IntComp;
  130.     String30        StringComp;
  131. };
  132.  
  133. typedef struct Record     RecordType;
  134. typedef RecordType *    RecordPtr;
  135. typedef int        boolean;
  136.  
  137. /* #define    NULL        0 */
  138. #define    TRUE        1
  139. #define    FALSE        0
  140.  
  141. extern Enumeration    Func1();
  142. extern boolean        Func2();
  143.  
  144. #include <stdlib.h>
  145. #include <stdio.h>
  146. #include <string.h>
  147. #include <time.h>
  148. #include <limits.h>
  149.  
  150. /*
  151.  * Package 1
  152.  */
  153. int        IntGlob;
  154. boolean        BoolGlob;
  155. char        Char1Glob;
  156. char        Char2Glob;
  157. Array1Dim    Array1Glob;
  158. Array2Dim    Array2Glob;
  159. RecordPtr    PtrGlb;
  160. RecordPtr    PtrGlbNext;
  161.  
  162. main()
  163. {
  164.     Proc0();
  165.     exit(0);
  166. }
  167.  
  168. Proc0()
  169. {
  170.     OneToFifty        IntLoc1;
  171.     OneToFifty        IntLoc2;
  172.     OneToFifty        IntLoc3;
  173.     char            CharIndex;
  174.     Enumeration         EnumLoc;
  175.     String30        String1Loc;
  176.     String30        String2Loc;
  177.     unsigned long        Loops = LOOPS;
  178.     unsigned long        LoopsPerSec;
  179.                       
  180.     unsigned long        startclock;
  181.     unsigned long        benchtime;
  182.     unsigned long        nulltime = 0;
  183.     register unsigned long    i;
  184.  
  185.         /* Make sure that we time long enough to measure loop overhead. */
  186.         /* Either use quarter of a second or whatever time is needed to */
  187.         /* get close to measuring the real loop overhead. */
  188.     printf("Calibrating ");
  189.     while ( (nulltime < (CLOCKS_PER_SEC/4)) || (nulltime < 4) )
  190.     {
  191.         Loops = Loops / 10 * 13;
  192.         printf(".");
  193.         startclock = clock();
  194.         for (i = 0; i < Loops; ++i);
  195.         nulltime = clock() - startclock;
  196.     }
  197.     printf(" Testing...\n");
  198.  
  199.     PtrGlbNext = (RecordPtr) malloc(sizeof(RecordType));
  200.     PtrGlb = (RecordPtr) malloc(sizeof(RecordType));
  201.     PtrGlb->PtrComp = PtrGlbNext;
  202.     PtrGlb->Discr = Ident1;
  203.     PtrGlb->EnumComp = Ident3;
  204.     PtrGlb->IntComp = 40;
  205.     strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM, SOME STRING");
  206.     strcpy(String1Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
  207.     Array2Glob[8][7] = 10;
  208.  
  209. /*****************
  210. -- Start Timer --
  211. *****************/
  212.     startclock = clock();
  213.     for (i = 0; i < Loops; ++i)
  214.     {
  215.         Proc5();
  216.         Proc4();
  217.         IntLoc1 = 2;
  218.         IntLoc2 = 3;
  219.         strcpy(String2Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
  220.         EnumLoc = Ident2;
  221.         BoolGlob = ! Func2(String1Loc, String2Loc);
  222.         while (IntLoc1 < IntLoc2)
  223.         {
  224.             IntLoc3 = 5 * IntLoc1 - IntLoc2;
  225.             Proc7(IntLoc1, IntLoc2, &IntLoc3);
  226.             ++IntLoc1;
  227.         }
  228.         Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
  229.         Proc1(PtrGlb);
  230.         for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex)
  231.             if (EnumLoc == Func1(CharIndex, 'C'))
  232.                 Proc6(Ident1, &EnumLoc);
  233.         IntLoc3 = IntLoc2 * IntLoc1;
  234.         IntLoc2 = IntLoc3 / IntLoc1;
  235.         IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1;
  236.         Proc2(&IntLoc1);
  237.     }
  238.  
  239. /*****************
  240. -- Stop Timer --
  241. *****************/
  242.  
  243.     benchtime = clock() - startclock - nulltime;
  244.     printf("Dhrystone(%s) time for %lu passes =%5.1lf seconds\n",
  245.         Version,
  246.         Loops, ((double)benchtime)/CLOCKS_PER_SEC);
  247.     LoopsPerSec = Loops / (((double)benchtime) / CLOCKS_PER_SEC);
  248.     printf("This machine benchmarks at %ld dhrystones/second\n", LoopsPerSec);
  249. }
  250.  
  251. Proc1(RecordPtr PtrParIn)
  252. {
  253. #define    NextRecord    (*(PtrParIn->PtrComp))
  254.  
  255.     structassign(NextRecord, *PtrGlb);
  256.     PtrParIn->IntComp = 5;
  257.     NextRecord.IntComp = PtrParIn->IntComp;
  258.     NextRecord.PtrComp = PtrParIn->PtrComp;
  259.     Proc3(NextRecord.PtrComp);
  260.     if (NextRecord.Discr == Ident1)
  261.     {
  262.         NextRecord.IntComp = 6;
  263.         Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp);
  264.         NextRecord.PtrComp = PtrGlb->PtrComp;
  265.         Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp);
  266.     }
  267.     else
  268.         structassign(*PtrParIn, NextRecord);
  269.  
  270. #undef    NextRecord
  271. }
  272.  
  273. Proc2(OneToFifty *IntParIO)
  274. {
  275.     OneToFifty        IntLoc;
  276.     Enumeration        EnumLoc;
  277.  
  278.     IntLoc = *IntParIO + 10;
  279.     for(;;)
  280.     {
  281.         if (Char1Glob == 'A')
  282.         {
  283.             --IntLoc;
  284.             *IntParIO = IntLoc - IntGlob;
  285.             EnumLoc = Ident1;
  286.         }
  287.         if (EnumLoc == Ident1)
  288.             break;
  289.     }
  290. }
  291.  
  292. Proc3(RecordPtr    *PtrParOut)
  293. {
  294.     if (PtrGlb != NULL)
  295.         *PtrParOut = PtrGlb->PtrComp;
  296.     else
  297.         IntGlob = 100;
  298.     Proc7(10, IntGlob, &PtrGlb->IntComp);
  299. }
  300.  
  301. Proc4()
  302. {
  303.     boolean    BoolLoc;
  304.  
  305.     BoolLoc = Char1Glob == 'A';
  306.     BoolLoc |= BoolGlob;
  307.     Char2Glob = 'B';
  308. }
  309.  
  310. Proc5()
  311. {
  312.     Char1Glob = 'A';
  313.     BoolGlob = FALSE;
  314. }
  315.  
  316. extern boolean Func3();
  317.  
  318. Proc6(Enumeration EnumParIn, Enumeration *EnumParOut)
  319. {
  320.     *EnumParOut = EnumParIn;
  321.     if (! Func3(EnumParIn) )
  322.         *EnumParOut = Ident4;
  323.     switch (EnumParIn)
  324.     {
  325.     case Ident1:    *EnumParOut = Ident1; break;
  326.     case Ident2:    if (IntGlob > 100) *EnumParOut = Ident1;
  327.             else *EnumParOut = Ident4;
  328.             break;
  329.     case Ident3:    *EnumParOut = Ident2; break;
  330.     case Ident4:    break;
  331.     case Ident5:    *EnumParOut = Ident3;
  332.     }
  333. }
  334.  
  335. Proc7(OneToFifty IntParI1, OneToFifty IntParI2, OneToFifty *IntParOut)
  336. {
  337.     OneToFifty    IntLoc;
  338.  
  339.     IntLoc = IntParI1 + 2;
  340.     *IntParOut = IntParI2 + IntLoc;
  341. }
  342.  
  343. Proc8(Array1Dim Array1Par, Array2Dim Array2Par, OneToFifty IntParI1, OneToFifty IntParI2)
  344. {
  345.     OneToFifty    IntLoc;
  346.     OneToFifty    IntIndex;
  347.  
  348.     IntLoc = IntParI1 + 5;
  349.     Array1Par[IntLoc] = IntParI2;
  350.     Array1Par[IntLoc+1] = Array1Par[IntLoc];
  351.     Array1Par[IntLoc+30] = IntLoc;
  352.     for (IntIndex = IntLoc; IntIndex <= (IntLoc+1); ++IntIndex)
  353.         Array2Par[IntLoc][IntIndex] = IntLoc;
  354.     ++Array2Par[IntLoc][IntLoc-1];
  355.     Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc];
  356.     IntGlob = 5;
  357. }
  358.  
  359. Enumeration Func1(CapitalLetter CharPar1, CapitalLetter CharPar2)
  360. {
  361.     CapitalLetter    CharLoc1;
  362.     CapitalLetter    CharLoc2;
  363.  
  364.     CharLoc1 = CharPar1;
  365.     CharLoc2 = CharLoc1;
  366.     if (CharLoc2 != CharPar2)
  367.         return (Ident1);
  368.     else
  369.         return (Ident2);
  370. }
  371.  
  372. boolean Func2(String30 StrParI1, String30 StrParI2)
  373. {
  374.     OneToThirty        IntLoc;
  375.     CapitalLetter        CharLoc;
  376.  
  377.     IntLoc = 1;
  378.     while (IntLoc <= 1)
  379.         if (Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1)
  380.         {
  381.             CharLoc = 'A';
  382.             ++IntLoc;
  383.         }
  384.     if (CharLoc >= 'W' && CharLoc <= 'Z')
  385.         IntLoc = 7;
  386.     if (CharLoc == 'X')
  387.         return(TRUE);
  388.     else
  389.     {
  390.         if (strcmp(StrParI1, StrParI2) > 0)
  391.         {
  392.             IntLoc += 7;
  393.             return (TRUE);
  394.         }
  395.         else
  396.             return (FALSE);
  397.     }
  398. }
  399.  
  400. boolean Func3(Enumeration EnumParIn)
  401. {
  402.     Enumeration    EnumLoc;
  403.  
  404.     EnumLoc = EnumParIn;
  405.     if (EnumLoc == Ident3) return (TRUE);
  406.     return (FALSE);
  407. }
  408.  
  409.