1 /* dhrystone - benchmark program */
6 * "DHRYSTONE" Benchmark Program
8 * Version: C/1.1, 12/01/84
10 * Date: PROGRAM updated 01/06/86, COMMENTS changed 01/31/87
12 * Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg.1013
13 * Translated from ADA by Rick Richardson
14 * Every method to preserve ADA-likeness has been used,
15 * at the expense of C-ness.
17 * Compile: cc -O dry.c -o drynr : No registers
18 * cc -O -DREG=register dry.c -o dryr : Registers
20 * Defines: Defines are provided for old C compiler's
21 * which don't have enums, and can't assign structures.
22 * The time(2) function is library dependant; Most
23 * return the time in seconds, but beware of some, like
24 * Aztec C, which return other units.
25 * The LOOPS define is initially set for 50000 loops.
26 * If you have a machine with large integers and is
27 * very fast, please change this number to 500000 to
28 * get better accuracy. Please select the way to
29 * measure the execution time using the TIME define.
30 * For single user machines, time(2) is adequate. For
31 * multi-user machines where you cannot get single-user
32 * access, use the times(2) function. Be careful to
33 * adjust the HZ parameter below for the units which
34 * are returned by your times(2) function. You can
35 * sometimes find this in <sys/param.h>. If you have
36 * neither time(2) nor times(2), use a stopwatch in
37 * the dead of the night.
38 * Use a "printf" at the point marked "start timer"
39 * to begin your timings. DO NOT use the UNIX "time(1)"
40 * command, as this will measure the total time to
41 * run this program, which will (erroneously) include
42 * the time to malloc(3) storage and to compute the
43 * time it takes to do nothing.
47 * Results: If you get any new machine/OS results, please send to:
49 * ihnp4!castor!pcrat!rick
51 * and thanks to all that do.
53 * Note: I order the list in increasing performance of the
54 * "with registers" benchmark. If the compiler doesn't
55 * provide register variables, then the benchmark
56 * is the same for both REG and NOREG.
58 * PLEASE: Send complete information about the machine type,
59 * clock speed, OS and C manufacturer/version. If
60 * the machine is modified, tell me what was done.
61 * On UNIX, execute uname -a and cc -V to get this info.
63 * 80x8x NOTE: 80x8x benchers: please try to do all memory models
64 * for a particular compiler.
67 * The following program contains statements of a high-level programming
68 * language (C) in a distribution considered representative:
71 * control statements 32%
72 * procedure, function calls 15%
74 * 100 statements are dynamically executed. The program is balanced with
75 * respect to the three aspects:
77 * - operand type (for simple data types)
79 * operand global, local, parameter, or constant.
81 * The combination of these three aspects is balanced only approximately.
83 * The program does not compute anything meaningfull, but it is
84 * syntactically and semantically correct.
89 #include <sys/types.h>
97 /* Accuracy of timings and human fatigue controlled by next two lines */
98 /*#define LOOPS 50000 */ /* Use this for slow or 16 bit machines */
99 /*#define LOOPS 500000 */ /* Use this for faster machines */
100 /*#define LOOPS (sizeof(int) == 2 ? 50000 : 1000000)*/
105 /* Compiler dependent options */
106 #define NOENUM /* Define if compiler has no enum's */
107 /* #define NOSTRUCTASSIGN */ /* Define if compiler can't assign structures*/
110 /* Define only one of the next two defines */
111 #define TIMES /* Use times(2) time function */
112 /*#define TIME */ /* Use time(2) time function */
116 /* Ganularity of time(2) is of course 1 second */
121 /* Define the granularity of your times(2) function */
122 /*#define HZ 50 */ /* times(2) returns 1/50 second (europe?) */
123 /*#define HZ 60 */ /* times(2) returns 1/60 second (most) */
124 /*#define HZ 100 */ /* times(2) returns 1/100 second (WECo) */
127 /* For compatibility with goofed up version */
128 /*#undef GOOF */ /* Define if you want the goofed up version */
132 char Version
[] = "1.0";
134 char Version
[] = "1.1";
138 #ifdef NOSTRUCTASSIGN
139 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
141 #define structassign(d, s) d = s
151 typedef int Enumeration
;
154 Ident1
, Ident2
, Ident3
, Ident4
, Ident5
158 typedef int OneToThirty
;
159 typedef int OneToFifty
;
160 typedef char CapitalLetter
;
161 typedef char String30
[31];
162 typedef int Array1Dim
[51];
163 typedef int Array2Dim
[51][51];
166 struct Record
*PtrComp
;
168 Enumeration EnumComp
;
173 typedef struct Record RecordType
;
174 typedef RecordType
*RecordPtr
;
191 #include <sys/times.h>
195 #define _PROTOTYPE(fun, args) fun args
198 _PROTOTYPE(int main
, (void));
199 _PROTOTYPE(void prep_timer
, (void));
200 _PROTOTYPE(void timeout
, (int sig
));
201 _PROTOTYPE(void Proc0
, (void));
202 _PROTOTYPE(void Proc1
, (RecordPtr PtrParIn
));
203 _PROTOTYPE(void Proc2
, (OneToFifty
*IntParIO
));
204 _PROTOTYPE(void Proc3
, (RecordPtr
*PtrParOut
));
205 _PROTOTYPE(void Proc4
, (void));
206 _PROTOTYPE(void Proc5
, (void));
207 _PROTOTYPE(void Proc6
, (Enumeration EnumParIn
, Enumeration
*EnumParOut
));
208 _PROTOTYPE(void Proc7
, (OneToFifty IntParI1
, OneToFifty IntParI2
,
209 OneToFifty
*IntParOut
));
210 _PROTOTYPE(void Proc8
, (Array1Dim Array1Par
, Array2Dim Array2Par
,
211 OneToFifty IntParI1
, OneToFifty IntParI2
));
212 /*_PROTOTYPE(Enumeration Func1,(CapitalLetter CharPar1, CapitalLetter CharPar2));*/
213 _PROTOTYPE(boolean Func2
, (String30 StrParI1
, String30 StrParI2
));
214 _PROTOTYPE(boolean Func3
, (Enumeration EnumParIn
));
216 _PROTOTYPE(Enumeration Func1
, (int CharPar1
, int CharPar2
));
234 signal(SIGALRM
, timeout
);
249 Array1Dim Array1Glob
;
250 Array2Dim Array2Glob
;
252 RecordPtr PtrGlbNext
;
258 REG OneToFifty IntLoc2
;
264 register unsigned long i
;
265 unsigned long starttime
;
266 unsigned long benchtime
;
267 unsigned long nulltime
;
268 unsigned long nullloops
;
269 unsigned long benchloops
;
270 unsigned long ticks_per_sec
;
276 #define ticks_per_sec HZ
278 ticks_per_sec
= sysconf(_SC_CLK_TCK
);
285 starttime
= time((long *) 0);
290 starttime
= tms
.tms_utime
;
297 nulltime
= time((long *) 0) - starttime
; /* Computes o'head of loop */
302 nulltime
= tms
.tms_utime
- starttime
; /* Computes overhead of looping */
308 PtrGlbNext
= (RecordPtr
) malloc(sizeof(RecordType
));
309 PtrGlb
= (RecordPtr
) malloc(sizeof(RecordType
));
310 PtrGlb
->PtrComp
= PtrGlbNext
;
311 PtrGlb
->Discr
= Ident1
;
312 PtrGlb
->EnumComp
= Ident3
;
313 PtrGlb
->IntComp
= 40;
314 strcpy(PtrGlb
->StringComp
, "DHRYSTONE PROGRAM, SOME STRING");
316 strcpy(String1Loc
, "DHRYSTONE PROGRAM, 1'ST STRING"); /* GOOF */
319 Array2Glob
[8][7] = 10; /* Was missing in published program */
329 starttime
= time((long *) 0);
334 starttime
= tms
.tms_utime
;
344 strcpy(String2Loc
, "DHRYSTONE PROGRAM, 2'ND STRING");
346 BoolGlob
= !Func2(String1Loc
, String2Loc
);
347 while (IntLoc1
< IntLoc2
) {
348 IntLoc3
= 5 * IntLoc1
- IntLoc2
;
349 Proc7(IntLoc1
, IntLoc2
, &IntLoc3
);
352 Proc8(Array1Glob
, Array2Glob
, IntLoc1
, IntLoc3
);
354 for (CharIndex
= 'A'; CharIndex
<= Char2Glob
; ++CharIndex
)
355 if (EnumLoc
== Func1(CharIndex
, 'C'))
356 Proc6(Ident1
, &EnumLoc
);
357 IntLoc3
= IntLoc2
* IntLoc1
;
358 IntLoc2
= IntLoc3
/ IntLoc1
;
359 IntLoc2
= 7 * (IntLoc3
- IntLoc2
) - IntLoc1
;
370 benchtime
= time((long *) 0) - starttime
;
375 benchtime
= tms
.tms_utime
- starttime
;
379 /* Approximately correct benchtime to the nulltime. */
380 benchtime
-= nulltime
/ (nullloops
/ benchloops
);
382 printf("Dhrystone(%s) time for %lu passes = %lu.%02lu\n",
384 benchloops
, benchtime
/ ticks_per_sec
,
385 benchtime
% ticks_per_sec
* 100 / ticks_per_sec
);
386 printf("This machine benchmarks at %lu dhrystones/second\n",
387 benchloops
* ticks_per_sec
/ benchtime
);
392 REG RecordPtr PtrParIn
;
394 #define NextRecord (*(PtrParIn->PtrComp))
397 structassign(NextRecord
, *PtrGlb
);
398 PtrParIn
->IntComp
= 5;
399 NextRecord
.IntComp
= PtrParIn
->IntComp
;
400 NextRecord
.PtrComp
= PtrParIn
->PtrComp
;
401 Proc3((RecordPtr
*)NextRecord
.PtrComp
);
402 if (NextRecord
.Discr
== Ident1
) {
403 NextRecord
.IntComp
= 6;
404 Proc6(PtrParIn
->EnumComp
, &NextRecord
.EnumComp
);
405 NextRecord
.PtrComp
= PtrGlb
->PtrComp
;
406 Proc7(NextRecord
.IntComp
, 10, &NextRecord
.IntComp
);
408 structassign(*PtrParIn
, NextRecord
);
416 OneToFifty
*IntParIO
;
418 REG OneToFifty IntLoc
;
419 REG Enumeration EnumLoc
;
422 IntLoc
= *IntParIO
+ 10;
424 if (Char1Glob
== 'A') {
426 *IntParIO
= IntLoc
- IntGlob
;
429 if (EnumLoc
== Ident1
) break;
434 void Proc3(PtrParOut
)
435 RecordPtr
*PtrParOut
;
438 *PtrParOut
= PtrGlb
->PtrComp
;
441 Proc7(10, IntGlob
, &PtrGlb
->IntComp
);
450 BoolLoc
= Char1Glob
== 'A';
463 void Proc6(EnumParIn
, EnumParOut
)
464 REG Enumeration EnumParIn
;
465 REG Enumeration
*EnumParOut
;
467 *EnumParOut
= EnumParIn
;
468 if (!Func3(EnumParIn
)) *EnumParOut
= Ident4
;
470 case Ident1
: *EnumParOut
= Ident1
; break;
473 *EnumParOut
= Ident1
;
475 *EnumParOut
= Ident4
;
477 case Ident3
: *EnumParOut
= Ident2
; break;
480 case Ident5
: *EnumParOut
= Ident3
;
485 void Proc7(IntParI1
, IntParI2
, IntParOut
)
488 OneToFifty
*IntParOut
;
490 REG OneToFifty IntLoc
;
493 IntLoc
= IntParI1
+ 2;
494 *IntParOut
= IntParI2
+ IntLoc
;
498 void Proc8(Array1Par
, Array2Par
, IntParI1
, IntParI2
)
504 REG OneToFifty IntLoc
;
505 REG OneToFifty IntIndex
;
508 IntLoc
= IntParI1
+ 5;
509 Array1Par
[IntLoc
] = IntParI2
;
510 Array1Par
[IntLoc
+ 1] = Array1Par
[IntLoc
];
511 Array1Par
[IntLoc
+ 30] = IntLoc
;
512 for (IntIndex
= IntLoc
; IntIndex
<= (IntLoc
+ 1); ++IntIndex
)
513 Array2Par
[IntLoc
][IntIndex
] = IntLoc
;
514 ++Array2Par
[IntLoc
][IntLoc
- 1];
515 Array2Par
[IntLoc
+ 20][IntLoc
] = Array1Par
[IntLoc
];
520 Enumeration
Func1(CharPar1
, CharPar2
)
521 CapitalLetter CharPar1
;
522 CapitalLetter CharPar2
;
524 REG CapitalLetter CharLoc1
;
525 REG CapitalLetter CharLoc2
;
530 if (CharLoc2
!= CharPar2
)
537 boolean
Func2(StrParI1
, StrParI2
)
541 REG OneToThirty IntLoc
;
542 REG CapitalLetter CharLoc
;
547 if (Func1(StrParI1
[IntLoc
], StrParI2
[IntLoc
+ 1]) == Ident1
) {
551 if (CharLoc
>= 'W' && CharLoc
<= 'Z') IntLoc
= 7;
555 if (strcmp(StrParI1
, StrParI2
) > 0) {
564 boolean
Func3(EnumParIn
)
565 REG Enumeration EnumParIn
;
567 REG Enumeration EnumLoc
;
571 if (EnumLoc
== Ident3
) return(TRUE
);
576 #ifdef NOSTRUCTASSIGN
582 while (l
--) *d
++ = *s
++;