home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / sysutils / benchmrk / drystone / dry.c < prev    next >
Encoding:
Text File  |  1990-07-19  |  15.1 KB  |  494 lines

  1. /*
  2.  * Date: 1990-07-18
  3.  * Rony G. Flatscher (RONY@AWIWUW11.BITNET)
  4.  *
  5.  * Following source of a dhrystone benchmark was compiled for IBM OS/2 V1.1
  6.  * (family application). Please note, that the benchmark differs in its
  7.  * results depending on the compiler optimizations! (IBM PS2/70, 80386-25Mhz,
  8.  * benchmarks at approx. 10.000 dhrystones under DOS and OS/2 using Microsofts
  9.  * Compiler V.5.1, but 17.000 dhrystones under IBM's AIX using the
  10.  * AIX-compiler!!!)
  11.  *
  12.  * There exists another dhrystone benchmark version, which I will get in some
  13.  * days that supposedly is programmed in a way that should inhibit "too good"
  14.  * of an optimization. If interested I shall submit it to the OS/2 list.
  15. */
  16. /*
  17.  *
  18.  * Date: Thu, 31 Oct 85 13:02:29 cst
  19.  * From: dongarra@anl-mcs.ARPA (Jack)
  20.  * Subject: dhrystone from benchmark
  21.  * Apparently-To: dymond@nbs-vms.ARPA
  22.  * Caveat receptor.  (Jack) dongarra@anl-mcs, (Eric Grosse) research!ehg
  23. */
  24. /*
  25.  *      "DHRYSTONE" Benchmark Program
  26.  *
  27.  *      Version:        C/1
  28.  *      Date:           12/01/84, RESULTS updated 10/15/85
  29.  *      Author:         Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg. 1013
  30.  *                      Translated from ADA by Rick Richardson
  31.  *                      Every method to preserve ADA-likeness has been used,
  32.  *                      at the expense of C-ness.
  33.  *      Compile:        cc -O dry.c -o drynr                    : No registers
  34.  *                      cc -O -DREG=register dry.c -o dryr      : Registers
  35.  *      Defines:        Defines are provided for old C compiler's
  36.  *                      which don't have enums, and can't assign structures.
  37.  *                      The time(2) function is library dependant; One is
  38.  *                      provided for CI-C86.  Your compiler may be different.
  39.  *      Run:            drynr; dryr
  40.  *                      50000 Runs are made and the time is printed
  41.  *      Results:        If you get any new machine/OS results, please send to:
  42.  *                              ..!houxm!vaximile!rer
  43.  *                      and thanks to all that do.  Space prevents listing
  44.  *                      the names of those who have provided some of these
  45.  *                      results.
  46.  *
  47.  * MACHINE      MICROPROCESSOR  OPERATING       COMPILER        DHRYSTONES/SEC.
  48.  * TYPE                         SYSTEM                          NO REG  REGS
  49.  * --------------------------   ------------    -----------     ---------------
  50.  * IBM PC/XT    8088-4.77Mhz    PCDOS 2.1       CI-C86 2.1      ????    ????
  51.  * IBM PC/XT    8088-4.77Mhz    PC/IX           cc              ????    ????
  52.  * Lisa         68000-7.7Mhz    ????            ??              ????    ????
  53.  * IBM PC/XT    8088-4.77Mhz    VENIX/86 2.0    cc               297     324
  54.  * ATT PC6300   8086-8Mhz       MSDOS 2.11      b16cc 2.0        632     684
  55.  * IBM PC/AT    80286-6Mhz      PCDOS 3.0       CI-C86 2.1       666     684
  56.  * Macintosh    68000-7.7Mhz    -               MegaMax C 2.0    661     709
  57.  * ATT PC6300   8086-8Mhz       MSDOS 2.11      CI-C86 2.20M     769     769
  58.  * ATT 3B2/300  MAC32-?Mhz      UNIX 5.0.2      cc               735     806
  59.  * Fast Mac     68000-7.7Mhz    -               MegaMax C 2.0    839     904 +
  60.  * IBM PC/AT    80286-6Mhz      VENIX/86 2.1    cc               961    1000
  61.  * VAX 11/750   -               VMS             VAX-11 C 2.0     958    1091
  62.  * ATT PC7300   68010-10Mhz     UNIX 5.2        cc              1041    1111
  63.  * Sun2/120     68010-10Mhz     Sun 4.2BSD      cc              1136    1219
  64.  * PDP 11/70    -               UNIX 5.2        cc              1162    1250
  65.  * IBM PC/AT    80286-7.5Mhz    VENIX/86 2.1    cc              1190    1315 *
  66.  * VAX 11/780   -               UNIX 5.2        cc              1515    1562
  67.  * ATT 3B20     -               UNIX 5.2        cc              1515    1724
  68.  * Gould PN6005 -               UTX 1.1(4.2BSD) cc              1675    1964
  69.  * Amdahl 580   -               UTS 5.0 Rel 1.2 cc Ver. 1.5    23076   23076
  70.  *
  71.  * IBM PS2/80   80386-20Mhz     DOS 3.3         MSC Ver 5.1     6501    6410
  72.  * IBM PS2/70   80386-25Mhz     OS/2 1.1        MSC Ver 5.1     9940    9940
  73.  * IBM PS2/70   80386-25Mhz     DOS 3.3         MSC Ver 5.1    10224   10101
  74.  * IBM PS2/70   80386-25Mhz     OS/2 1.1, four (4) background tasks,
  75.  *                              adding up to                   10205   10185
  76.  *
  77.  *   * 15Mhz crystal substituted for original 12Mhz;
  78.  *   + This Macintosh was upgraded from 128K to 512K in such a way that
  79.  *     the new 384K of memory is not slowed down by video generator accesses.
  80.  *
  81.  **************************************************************************
  82.  *
  83.  *      The following program contains statements of a high-level programming
  84.  *      language (C) in a distribution considered representative:
  85.  *
  86.  *      assignments                     53%
  87.  *      control statements              32%
  88.  *      procedure, function calls       15%
  89.  *
  90.  *      100 statements are dynamically executed.  The program is balanced with
  91.  *      respect to the three aspects:
  92.  *              - statement type
  93.  *              - operand type (for simple data types)
  94.  *              - operand access
  95.  *                      operand global, local, parameter, or constant.
  96.  *
  97.  *      The combination of these three aspects is balanced only approximately.
  98.  *
  99.  *      The program does not compute anything meaningfull, but it is
  100.  *      syntactically and semantically correct.
  101.  *
  102.  */
  103.  
  104. #ifdef MESSY_DOS
  105. /* Compiler dependent options */
  106. /* Define the following 3 symbols for IBM PC/XT w/ Supersoft C. KMD. NBS */
  107. #include "stdio.h"
  108. #define  NOENUM                 /* Define if compiler has no enum's */
  109. #define  NOSTRUCTASSIGN         /* Define if compiler can't assign structures */
  110. #define  NOTIME                 /* Define if no time() function in library */
  111. #endif
  112.  
  113. #ifdef OS2
  114. #define INCL_BASE
  115. #define INCL_DOS
  116. #define INCL_NOCOMMON
  117. #include <os2.h>
  118. #endif
  119.  
  120. #ifdef EXACT
  121. double ftimeit();
  122. #define TIMEIT ftimeit()
  123. #else
  124. #define TIMEIT time(0)
  125. #endif
  126.  
  127. #ifdef  NOSTRUCTASSIGN
  128. #define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
  129. #else
  130. #define structassign(d, s)      d = s
  131. #endif
  132.  
  133. #ifdef  NOENUM
  134. #define Ident1  1
  135. #define Ident2  2
  136. #define Ident3  3
  137. #define Ident4  4
  138. #define Ident5  5
  139. typedef int     Enumeration;
  140. #else
  141. typedef enum    {Ident1, Ident2, Ident3, Ident4, Ident5} Enumeration;
  142. #endif
  143.  
  144. typedef int     OneToThirty;
  145. typedef int     OneToFifty;
  146. typedef char    CapitalLetter;
  147. typedef char    String30[31];
  148. typedef int     Array1Dim[51];
  149. typedef int     Array2Dim[51][51];
  150.  
  151. struct  Record
  152. {
  153.         struct Record           *PtrComp;
  154.         Enumeration             Discr;
  155.         Enumeration             EnumComp;
  156.         OneToFifty              IntComp;
  157.         String30                StringComp;
  158. };
  159.  
  160. typedef struct Record   RecordType;
  161. typedef RecordType *    RecordPtr;
  162. typedef int             boolean;
  163.  
  164. #define NULL            0
  165. #define TRUE            1
  166. #define FALSE           0
  167.  
  168. #ifndef REG
  169. #define REG
  170. #endif
  171.  
  172. extern Enumeration      Func1();
  173. extern boolean          Func2();
  174.  
  175. main()
  176. {
  177.         Proc0();
  178.         exit(0);
  179. }
  180.  
  181. /*
  182.  * Package 1
  183.  */
  184. int             IntGlob;
  185. boolean         BoolGlob;
  186. char            Char1Glob;
  187. char            Char2Glob;
  188. Array1Dim       Array1Glob;
  189. Array2Dim       Array2Glob;
  190. RecordPtr       PtrGlb;
  191. RecordPtr       PtrGlbNext;
  192.  
  193. Proc0()
  194. {
  195.         OneToFifty              IntLoc1;
  196.         REG OneToFifty          IntLoc2;
  197.         OneToFifty              IntLoc3;
  198.         REG char                CharLoc;
  199.         REG char                CharIndex;
  200.         Enumeration             EnumLoc;
  201.         String30                String1Loc;
  202.         String30                String2Loc;
  203.  
  204. #define LOOPS           50000
  205. #ifdef EXACT
  206. double                  starttime;
  207. double                  benchtime;
  208. double                  nulltime;
  209. #else
  210. long                    time();
  211. long                    starttime;
  212. long                    benchtime;
  213. long                    nulltime;
  214. #endif
  215.  
  216. register unsigned int   i;
  217. starttime = TIMEIT;
  218. for (i = 0; i < LOOPS; ++i);
  219. nulltime = TIMEIT - starttime;
  220.  
  221.         PtrGlbNext = (RecordPtr) malloc(sizeof(RecordType));
  222.         PtrGlb = (RecordPtr) malloc(sizeof(RecordType));
  223.         PtrGlb->PtrComp = PtrGlbNext;
  224.         PtrGlb->Discr = Ident1;
  225.         PtrGlb->EnumComp = Ident3;
  226.         PtrGlb->IntComp = 40;
  227.         strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM, SOME STRING");
  228.  
  229. /*****************
  230. -- Start Timer --
  231. *****************/
  232. starttime = TIMEIT;
  233. for (i = 0; i < LOOPS; ++i)
  234. {
  235.  
  236.         Proc5();
  237.         Proc4();
  238.         IntLoc1 = 2;
  239.         IntLoc2 = 3;
  240.         strcpy(String2Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
  241.         EnumLoc = Ident2;
  242.         BoolGlob = ! Func2(String1Loc, String2Loc);
  243.         while (IntLoc1 < IntLoc2)
  244.         {
  245.                 IntLoc3 = 5 * IntLoc1 - IntLoc2;
  246.                 Proc7(IntLoc1, IntLoc2, &IntLoc3);
  247.                 ++IntLoc1;
  248.         }
  249.         Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
  250.         Proc1(PtrGlb);
  251.         for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex)
  252.                 if (EnumLoc == Func1(CharIndex, 'C'))
  253.                         Proc6(Ident1, &EnumLoc);
  254.         IntLoc3 = IntLoc2 * IntLoc1;
  255.         IntLoc2 = IntLoc3 / IntLoc1;
  256.         IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1;
  257.         Proc2(&IntLoc1);
  258.  
  259. /*****************
  260. -- Stop Timer --
  261. *****************/
  262. }
  263. benchtime = TIMEIT - starttime - nulltime;
  264. #ifdef EXACT
  265. printf("(%ld Durchläufe)     ", (long) LOOPS);
  266. printf("Dhrystone Zeit:  %5.2fsek | ", benchtime);
  267. printf("Dhrystones/sek:  %6ld\n",
  268.         (long) (((long) LOOPS) / benchtime));
  269. #else
  270. printf("Dhrystone time for %ld passes = %ld\n", (long) LOOPS, benchtime);
  271. printf("This machine benchmarks at %ld dhrystones/second\n",
  272.         ((long) LOOPS) / benchtime);
  273. #endif
  274.  
  275. }
  276.  
  277. Proc1(PtrParIn)
  278. REG RecordPtr   PtrParIn;
  279. {
  280. #define NextRecord      (*(PtrParIn->PtrComp))
  281.  
  282.         structassign(NextRecord, *PtrGlb);
  283.         PtrParIn->IntComp = 5;
  284.         NextRecord.IntComp = PtrParIn->IntComp;
  285.         NextRecord.PtrComp = PtrParIn->PtrComp;
  286.         Proc3(NextRecord.PtrComp);
  287.         if (NextRecord.Discr == Ident1)
  288.         {
  289.                 NextRecord.IntComp = 6;
  290.                 Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp);
  291.                 NextRecord.PtrComp = PtrGlb->PtrComp;
  292.                 Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp);
  293.         }
  294.         else
  295.                 structassign(*PtrParIn, NextRecord);
  296.  
  297. #undef  NextRecord
  298. }
  299.  
  300. Proc2(IntParIO)
  301. OneToFifty      *IntParIO;
  302. {
  303.         REG OneToFifty          IntLoc;
  304.         REG Enumeration         EnumLoc;
  305.  
  306.         IntLoc = *IntParIO + 10;
  307.         for(;;)
  308.         {
  309.                 if (Char1Glob == 'A')
  310.                 {
  311.                         --IntLoc;
  312.                         *IntParIO = IntLoc - IntGlob;
  313.                         EnumLoc = Ident1;
  314.                 }
  315.                 if (EnumLoc == Ident1)
  316.                         break;
  317.         }
  318. }
  319.  
  320. Proc3(PtrParOut)
  321. RecordPtr       *PtrParOut;
  322. {
  323.         if (PtrGlb != NULL)
  324.                 *PtrParOut = PtrGlb->PtrComp;
  325.         else
  326.                 IntGlob = 100;
  327.         Proc7(10, IntGlob, &PtrGlb->IntComp);
  328. }
  329.  
  330. Proc4()
  331. {
  332.         REG boolean     BoolLoc;
  333.  
  334.         BoolLoc = Char1Glob == 'A';
  335.         BoolLoc |= BoolGlob;
  336.         Char2Glob = 'B';
  337. }
  338.  
  339. Proc5()
  340. {
  341.         Char1Glob = 'A';
  342.         BoolGlob = FALSE;
  343. }
  344.  
  345. extern boolean Func3();
  346.  
  347. Proc6(EnumParIn, EnumParOut)
  348. REG Enumeration EnumParIn;
  349. REG Enumeration *EnumParOut;
  350. {
  351.         *EnumParOut = EnumParIn;
  352.         if (! Func3(EnumParIn) )
  353.                 *EnumParOut = Ident4;
  354.         switch (EnumParIn)
  355.         {
  356.         case Ident1:    *EnumParOut = Ident1; break;
  357.         case Ident2:    if (IntGlob > 100) *EnumParOut = Ident1;
  358.                         else *EnumParOut = Ident4;
  359.                         break;
  360.         case Ident3:    *EnumParOut = Ident2; break;
  361.         case Ident4:    break;
  362.         case Ident5:    *EnumParOut = Ident3;
  363.         }
  364. }
  365.  
  366. Proc7(IntParI1, IntParI2, IntParOut)
  367. OneToFifty      IntParI1;
  368. OneToFifty      IntParI2;
  369. OneToFifty      *IntParOut;
  370. {
  371.         REG OneToFifty  IntLoc;
  372.  
  373.         IntLoc = IntParI1 + 2;
  374.         *IntParOut = IntParI2 + IntLoc;
  375. }
  376.  
  377. Proc8(Array1Par, Array2Par, IntParI1, IntParI2)
  378. Array1Dim       Array1Par;
  379. Array2Dim       Array2Par;
  380. OneToFifty      IntParI1;
  381. OneToFifty      IntParI2;
  382. {
  383.         REG OneToFifty  IntLoc;
  384.         REG OneToFifty  IntIndex;
  385.  
  386.         IntLoc = IntParI1 + 5;
  387.         Array1Par[IntLoc] = IntParI2;
  388.         Array1Par[IntLoc+1] = Array1Par[IntLoc];
  389.         Array1Par[IntLoc+30] = IntLoc;
  390.         for (IntIndex = IntLoc; IntIndex <= (IntLoc+1); ++IntIndex)
  391.                 Array2Par[IntLoc][IntIndex] = IntLoc;
  392.         ++Array2Par[IntLoc][IntLoc-1];
  393.         Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc];
  394.         IntGlob = 5;
  395. }
  396.  
  397. Enumeration Func1(CharPar1, CharPar2)
  398. CapitalLetter   CharPar1;
  399. CapitalLetter   CharPar2;
  400. {
  401.         REG CapitalLetter       CharLoc1;
  402.         REG CapitalLetter       CharLoc2;
  403.  
  404.         CharLoc1 = CharPar1;
  405.         CharLoc2 = CharLoc1;
  406.         if (CharLoc2 != CharPar2)
  407.                 return (Ident1);
  408.         else
  409.                 return (Ident2);
  410. }
  411.  
  412. boolean Func2(StrParI1, StrParI2)
  413. String30        StrParI1;
  414. String30        StrParI2;
  415. {
  416.         REG OneToThirty         IntLoc;
  417.         REG CapitalLetter       CharLoc;
  418.  
  419.         IntLoc = 1;
  420.         while (IntLoc <= 1)
  421.                 if (Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1)
  422.                 {
  423.                         CharLoc = 'A';
  424.                         ++IntLoc;
  425.                 }
  426.         if (CharLoc >= 'W' && CharLoc <= 'Z')
  427.                 IntLoc = 7;
  428.         if (CharLoc == 'X')
  429.                 return(TRUE);
  430.         else
  431.         {
  432.                 if (strcmp(StrParI1, StrParI2) > 0)
  433.                 {
  434.                         IntLoc += 7;
  435.                         return (TRUE);
  436.                 }
  437.                 else
  438.                         return (FALSE);
  439.         }
  440. }
  441.  
  442. boolean Func3(EnumParIn)
  443. REG Enumeration EnumParIn;
  444. {
  445.         REG Enumeration EnumLoc;
  446.  
  447.         EnumLoc = EnumParIn;
  448.         if (EnumLoc == Ident3) return (TRUE);
  449.         return (FALSE);
  450. }
  451.  
  452. #ifdef  NOSTRUCTASSIGN
  453. memcpy(d, s, l)
  454. register char   *d;
  455. register char   *s;
  456. int     l;
  457. {
  458.         while (l--) *d++ = *s++;
  459. }
  460. #endif
  461.  
  462. /*
  463.  *      Library function for compilers with no time(2) function in the
  464.  *      library.
  465.  */
  466. #ifdef  NOTIME
  467. long    time(p)
  468. long    *p;
  469. {               /* CI-C86 time function - don't use around midnight */
  470.         long    t;
  471.         struct regval {unsigned int ax,bx,cx,dx,si,di,ds,es; } regs;
  472.  
  473.         regs.ax = 0x2c00;
  474.         sysint21(®s, ®s);
  475.         t = ((regs.cx>>8)*60L + (regs.cx & 0xff))*60L + (regs.dx>>8);
  476.         if (p) *p = t;
  477.         return t;
  478. }
  479. #endif
  480.  
  481. #ifdef EXACT
  482. #include <sys/types.h>
  483. #include <sys/timeb.h>
  484. double
  485. ftimeit()
  486. {
  487.         void ftime();
  488.         struct timeb timebuffer;
  489.         ftime(&timebuffer);
  490.         return(timebuffer.time + timebuffer.millitm / 1000.0 );
  491. }
  492. #endif
  493.  
  494.