home *** CD-ROM | disk | FTP | other *** search
- /*
- * "DHRYSTONE" Benchmark Program
- *
- * Version: C/1.1,
- *
- * Date: PROGRAM updated 02 Feb 95, RESULTS updated 03/31/86
- *
- * Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013
- * Translated from ADA by Rick Richardson.
- * Translated from C to ANSI C by James Day.
- *
- * ANSI notes: I corrected a bug where the Loop counter was an int which on 16
- * bit machines caused an infinite loop where more than UINT_MAX
- * (62768) loops were used. The one second clock resolution was not
- * high enough to measure the loop overhead so I both converted the
- * program to use the ANSI clock routine which has finer resolution
- * and ensured that the empty loop takes a measurable number
- * of clock ticks to execute. This is the calibration phase
- * that the program mentions at the start.
- * The core of the benchmark loop wasn't touched in the conversion.
- *
- * Note: I order the list in increasing performance of the
- * "with registers" benchmark. If the compiler doesn't
- * provide register variables, then the benchmark
- * is the same for both REG and NOREG.
- *
- * Warning: This code is highly susceptible to optimisation. You MUST
- * disable all significant loop optimisation and function call
- * inlining to get a meaningful result. Turning on all Microsoft
- * compiler options doubled the score compared to just using automatic
- * register assignment.
- *
- * RESULTS BEGIN HERE
- *
- *----------------DHRYSTONE VERSION 1.1 RESULTS BEGIN--------------------------
- *
- * MACHINE MICROPROCESSOR OPERATING COMPILER DHRYSTONES/SEC.
- * TYPE SYSTEM NO REG REGS
- * -------------------------- ------------ ----------- ---------------
- * Apple IIe 65C02-1.02Mhz DOS 3.3 Aztec CII v1.05i 37 37
- * - Z80-2.5Mhz CPM-80 v2.2 Aztec CII v1.05g 91 91
- * - 8086-8Mhz RMX86 V6 Intel C-86 V2.0 197 203LM??
- * IBM PC/XT 8088-4.77Mhz COHERENT 2.3.43 Mark Wiiliams 259 275
- * - 8086-8Mhz RMX86 V6 Intel C-86 V2.0 287 304 ??
- * Fortune 32:16 68000-6Mhz V7+sys3+4.1BSD cc 360 346
- * PDP-11/34A w/FP-11C UNIX V7m cc 406 449
- * Macintosh512 68000-7.7Mhz Mac ROM O/S DeSmet(C ware) 625 625
- * VAX-11/750 w/FPA UNIX 4.2BSD cc 831 852
- * DataMedia 932 68000-10Mhz UNIX sysV cc 837 888
- * Plexus P35 68000-12.5Mhz UNIX sysIII cc 835 894
- * ATT PC7300 68010-10Mhz UNIX 5.0.3 cc 973 1034
- * Compaq II 80286-8Mhz MSDOS 3.1 MS C 3.0 1086 1140 LM
- * IBM PC/AT 80286-7.5Mhz Venix/286 SVR2 cc 1159 1254 *15
- * Compaq II 80286-8Mhz MSDOS 3.1 MS C 3.0 1190 1282 MM
- * MicroVAX II - Mach/4.3 cc 1361 1385
- * DEC uVAX II - Ultrix-32m v1.1 cc 1385 1399
- * Compaq II 80286-8Mhz MSDOS 3.1 MS C 3.0 1351 1428
- * VAX 11/780 - UNIX 4.2BSD cc 1417 1441
- * VAX-780/MA780 Mach/4.3 cc 1428 1470
- * VAX 11/780 - UNIX 5.0.1 cc 4.1.1.31 1650 1640
- * Ridge 32C V1 - ROS 3.3 Ridge C (older) 1628 1695
- * Gould PN6005 - UTX 1.1c+ (4.2) cc 1732 1884
- * Gould PN9080 custom ECL UTX-32 1.1C cc 4745 4992
- * VAX-784 - Mach/4.3 cc 5263 5555 &4
- * VAX 8600 - 4.3 BSD cc 6329 6423
- * Amdahl 5860 - UTS sysV cc 1.22 28735 28846
- * IBM3090/200 - ? ? 31250 31250
- *
- * NOTE
- * * Crystal changed from 'stock' to listed value.
- * LM Large Memory Model. (Otherwise, all 80x8x results are small model)
- * MM Medium Memory Model. (Otherwise, all 80x8x results are small model)
- * &nn This machine has "nn" processors, and the benchmark results were
- * obtained by having all "nn" processors working on 1 copy of dhrystone.
- * (Note, this is different than Nnn. Salesmen like this measure).
- * ? I don't trust results marked with '?'. These were sent to me with
- * either incomplete info, or with times that just don't make sense.
- * ?? means I think the performance is too poor, ?! means too good.
- * If anybody can confirm these figures, please respond.
- *
- * ABBREVIATIONS
- * CCC Concurrent Computer Corp. (was Perkin-Elmer)
- * MC Masscomp
- *
- *--------------------------------RESULTS END----------------------------------
- *
- * The following program contains statements of a high-level programming
- * language (C) in a distribution considered representative:
- *
- * assignments 53%
- * control statements 32%
- * procedure, function calls 15%
- *
- * 100 statements are dynamically executed. The program is balanced with
- * respect to the three aspects:
- * - statement type
- * - operand type (for simple data types)
- * - operand access
- * operand global, local, parameter, or constant.
- *
- * The combination of these three aspects is balanced only approximately.
- *
- * The program does not compute anything meaningfull, but it is
- * syntactically and semantically correct.
- *
- */
-
- /* Next line sets the initial calibration loop count only. */
- #define LOOPS 10000
-
- char Version[] = "1.1";
-
- #define structassign(d, s) d = s
-
- typedef enum {Ident1, Ident2, Ident3, Ident4, Ident5} Enumeration;
-
- typedef int OneToThirty;
- typedef int OneToFifty;
- typedef char CapitalLetter;
- typedef char String30[31];
- typedef int Array1Dim[51];
- typedef int Array2Dim[51][51];
-
- struct Record
- {
- struct Record *PtrComp;
- Enumeration Discr;
- Enumeration EnumComp;
- OneToFifty IntComp;
- String30 StringComp;
- };
-
- typedef struct Record RecordType;
- typedef RecordType * RecordPtr;
- typedef int boolean;
-
- /* #define NULL 0 */
- #define TRUE 1
- #define FALSE 0
-
- extern Enumeration Func1();
- extern boolean Func2();
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <limits.h>
-
- /*
- * Package 1
- */
- int IntGlob;
- boolean BoolGlob;
- char Char1Glob;
- char Char2Glob;
- Array1Dim Array1Glob;
- Array2Dim Array2Glob;
- RecordPtr PtrGlb;
- RecordPtr PtrGlbNext;
-
- main()
- {
- Proc0();
- exit(0);
- }
-
- Proc0()
- {
- OneToFifty IntLoc1;
- OneToFifty IntLoc2;
- OneToFifty IntLoc3;
- char CharIndex;
- Enumeration EnumLoc;
- String30 String1Loc;
- String30 String2Loc;
- unsigned long Loops = LOOPS;
- unsigned long LoopsPerSec;
-
- unsigned long startclock;
- unsigned long benchtime;
- unsigned long nulltime = 0;
- register unsigned long i;
-
- /* Make sure that we time long enough to measure loop overhead. */
- /* Either use quarter of a second or whatever time is needed to */
- /* get close to measuring the real loop overhead. */
- printf("Calibrating ");
- while ( (nulltime < (CLOCKS_PER_SEC/4)) || (nulltime < 4) )
- {
- Loops = Loops / 10 * 13;
- printf(".");
- startclock = clock();
- for (i = 0; i < Loops; ++i);
- nulltime = clock() - startclock;
- }
- printf(" Testing...\n");
-
- PtrGlbNext = (RecordPtr) malloc(sizeof(RecordType));
- PtrGlb = (RecordPtr) malloc(sizeof(RecordType));
- PtrGlb->PtrComp = PtrGlbNext;
- PtrGlb->Discr = Ident1;
- PtrGlb->EnumComp = Ident3;
- PtrGlb->IntComp = 40;
- strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM, SOME STRING");
- strcpy(String1Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
- Array2Glob[8][7] = 10;
-
- /*****************
- -- Start Timer --
- *****************/
- startclock = clock();
- for (i = 0; i < Loops; ++i)
- {
- Proc5();
- Proc4();
- IntLoc1 = 2;
- IntLoc2 = 3;
- strcpy(String2Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
- EnumLoc = Ident2;
- BoolGlob = ! Func2(String1Loc, String2Loc);
- while (IntLoc1 < IntLoc2)
- {
- IntLoc3 = 5 * IntLoc1 - IntLoc2;
- Proc7(IntLoc1, IntLoc2, &IntLoc3);
- ++IntLoc1;
- }
- Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
- Proc1(PtrGlb);
- for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex)
- if (EnumLoc == Func1(CharIndex, 'C'))
- Proc6(Ident1, &EnumLoc);
- IntLoc3 = IntLoc2 * IntLoc1;
- IntLoc2 = IntLoc3 / IntLoc1;
- IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1;
- Proc2(&IntLoc1);
- }
-
- /*****************
- -- Stop Timer --
- *****************/
-
- benchtime = clock() - startclock - nulltime;
- printf("Dhrystone(%s) time for %lu passes =%5.1lf seconds\n",
- Version,
- Loops, ((double)benchtime)/CLOCKS_PER_SEC);
- LoopsPerSec = Loops / (((double)benchtime) / CLOCKS_PER_SEC);
- printf("This machine benchmarks at %ld dhrystones/second\n", LoopsPerSec);
- }
-
- Proc1(RecordPtr PtrParIn)
- {
- #define NextRecord (*(PtrParIn->PtrComp))
-
- structassign(NextRecord, *PtrGlb);
- PtrParIn->IntComp = 5;
- NextRecord.IntComp = PtrParIn->IntComp;
- NextRecord.PtrComp = PtrParIn->PtrComp;
- Proc3(NextRecord.PtrComp);
- if (NextRecord.Discr == Ident1)
- {
- NextRecord.IntComp = 6;
- Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp);
- NextRecord.PtrComp = PtrGlb->PtrComp;
- Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp);
- }
- else
- structassign(*PtrParIn, NextRecord);
-
- #undef NextRecord
- }
-
- Proc2(OneToFifty *IntParIO)
- {
- OneToFifty IntLoc;
- Enumeration EnumLoc;
-
- IntLoc = *IntParIO + 10;
- for(;;)
- {
- if (Char1Glob == 'A')
- {
- --IntLoc;
- *IntParIO = IntLoc - IntGlob;
- EnumLoc = Ident1;
- }
- if (EnumLoc == Ident1)
- break;
- }
- }
-
- Proc3(RecordPtr *PtrParOut)
- {
- if (PtrGlb != NULL)
- *PtrParOut = PtrGlb->PtrComp;
- else
- IntGlob = 100;
- Proc7(10, IntGlob, &PtrGlb->IntComp);
- }
-
- Proc4()
- {
- boolean BoolLoc;
-
- BoolLoc = Char1Glob == 'A';
- BoolLoc |= BoolGlob;
- Char2Glob = 'B';
- }
-
- Proc5()
- {
- Char1Glob = 'A';
- BoolGlob = FALSE;
- }
-
- extern boolean Func3();
-
- Proc6(Enumeration EnumParIn, Enumeration *EnumParOut)
- {
- *EnumParOut = EnumParIn;
- if (! Func3(EnumParIn) )
- *EnumParOut = Ident4;
- switch (EnumParIn)
- {
- case Ident1: *EnumParOut = Ident1; break;
- case Ident2: if (IntGlob > 100) *EnumParOut = Ident1;
- else *EnumParOut = Ident4;
- break;
- case Ident3: *EnumParOut = Ident2; break;
- case Ident4: break;
- case Ident5: *EnumParOut = Ident3;
- }
- }
-
- Proc7(OneToFifty IntParI1, OneToFifty IntParI2, OneToFifty *IntParOut)
- {
- OneToFifty IntLoc;
-
- IntLoc = IntParI1 + 2;
- *IntParOut = IntParI2 + IntLoc;
- }
-
- Proc8(Array1Dim Array1Par, Array2Dim Array2Par, OneToFifty IntParI1, OneToFifty IntParI2)
- {
- OneToFifty IntLoc;
- OneToFifty IntIndex;
-
- IntLoc = IntParI1 + 5;
- Array1Par[IntLoc] = IntParI2;
- Array1Par[IntLoc+1] = Array1Par[IntLoc];
- Array1Par[IntLoc+30] = IntLoc;
- for (IntIndex = IntLoc; IntIndex <= (IntLoc+1); ++IntIndex)
- Array2Par[IntLoc][IntIndex] = IntLoc;
- ++Array2Par[IntLoc][IntLoc-1];
- Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc];
- IntGlob = 5;
- }
-
- Enumeration Func1(CapitalLetter CharPar1, CapitalLetter CharPar2)
- {
- CapitalLetter CharLoc1;
- CapitalLetter CharLoc2;
-
- CharLoc1 = CharPar1;
- CharLoc2 = CharLoc1;
- if (CharLoc2 != CharPar2)
- return (Ident1);
- else
- return (Ident2);
- }
-
- boolean Func2(String30 StrParI1, String30 StrParI2)
- {
- OneToThirty IntLoc;
- CapitalLetter CharLoc;
-
- IntLoc = 1;
- while (IntLoc <= 1)
- if (Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1)
- {
- CharLoc = 'A';
- ++IntLoc;
- }
- if (CharLoc >= 'W' && CharLoc <= 'Z')
- IntLoc = 7;
- if (CharLoc == 'X')
- return(TRUE);
- else
- {
- if (strcmp(StrParI1, StrParI2) > 0)
- {
- IntLoc += 7;
- return (TRUE);
- }
- else
- return (FALSE);
- }
- }
-
- boolean Func3(Enumeration EnumParIn)
- {
- Enumeration EnumLoc;
-
- EnumLoc = EnumParIn;
- if (EnumLoc == Ident3) return (TRUE);
- return (FALSE);
- }
-
-