1 // See LICENSE for license details.
6 /****************** "DHRYSTONE" Benchmark Program ***************************/
7 #define Version "C, Version 2.2"
8 /* File: dhry_1.c (part 2 of 3)
9 * Author: Reinhold P. Weicker
10 * Siemens Nixdorf, Paderborn/Germany
11 * weicker@specbench.org
13 * Modified: Steven Pemberton, CWI, Amsterdam; Steven.Pemberton@cwi.nl
14 * Date: October, 1993; March 1995
15 * Included both files into one source, that gets compiled
16 * in two passes. Made program auto-compiling, and auto-running,
17 * and generally made it much easier to use.
19 * Original Version (in Ada) published in
20 * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
21 * pp. 1013 - 1030, together with the statistics
22 * on which the distribution of statements etc. is based.
24 * In this C version, the following C library functions are used:
25 * - strcpy, strcmp (inside the measurement loop)
26 * - printf, scanf (outside the measurement loop)
27 * In addition, Berkeley UNIX system calls "times ()" or "time ()"
28 * are used for execution time measurement. For measurements
29 * on other systems, these calls have to be changed.
31 * Collection of Results:
32 * Reinhold Weicker (address see above) and
36 * 94 Apple Orchard Drive
37 * Tinton Falls, NJ 07724
38 * Phone: (201) 389-8963 (9-17 EST)
39 * Usenet: ...!uunet!pcrat!rick
41 * Please send results to Rick Richardson and/or Reinhold Weicker.
42 * Complete information should be given on hardware and software used.
43 * Hardware information includes: Machine type, CPU, type and size
44 * of caches; for microprocessors: clock frequency, memory speed
45 * (number of wait states).
46 * Software information includes: Compiler (and runtime library)
47 * manufacturer and version, compilation switches, OS version.
48 * The Operating System version may give an indication about the compiler;
49 * Dhrystone itself performs no OS calls in the measurement loop.
51 * The complete output generated by the program should be mailed
52 * such that at least some checks for correctness can be made.
54 ***************************************************************************
56 * Defines: The following "Defines" are possible:
57 * -DREG (default: Not defined)
58 * As an approximation to what an average C programmer
59 * might do, causes the "register" storage class to be applied
60 * - for local variables, if they are used (dynamically)
62 * - for parameters if they are used (dynamically)
64 * Note that an optimal "register" strategy is
65 * compiler-dependent, and that "register" declarations
66 * do not necessarily lead to faster execution.
67 * -DNOSTRUCTASSIGN (default: Not defined)
68 * Define if the C compiler does not support
69 * assignment of structures.
70 * -DNOENUMS (default: Not defined)
71 * Define if the C compiler does not support
75 * The "times" function of UNIX (returning process times)
76 * or the "time" function (returning wallclock time)
77 * is used for measurement.
78 * For single user machines, "time ()" is adequate. For
79 * multi-user machines where you cannot get single-user
80 * access, use the "times ()" function. If you have
81 * neither, use a stopwatch in the dead of night.
82 * "printf"s are provided marking the points "Start Timer"
83 * and "Stop Timer". DO NOT use the UNIX "time(1)"
84 * command, as this will measure the total time to
85 * run this program, which will (erroneously) include
86 * the time to allocate storage (malloc) and to perform
89 * In Berkeley UNIX, the function "times" returns process
90 * time in 1/HZ seconds, with HZ = 60 for most systems.
91 * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
94 ***************************************************************************
96 * History: Version C/2.1 was made for two reasons:
98 * 1) There was an obvious need for a common C version of
99 * Dhrystone, since C is at present the most popular system
100 * programming language for the class of processors
101 * (microcomputers, minicomputers) where Dhrystone is used most.
102 * There should be, as far as possible, only one C version of
103 * Dhrystone such that results can be compared without
104 * restrictions. In the past, the C versions distributed
105 * by Rick Richardson (Version 1.1) and by Reinhold Weicker
106 * had small (though not significant) differences.
108 * 2) As far as it is possible without changes to the Dhrystone
109 * statistics, optimizing compilers should be prevented from
110 * removing significant statements.
112 * This C version has been developed in cooperation with
113 * Rick Richardson (Tinton Falls, NJ), it incorporates many
114 * ideas from the "Version 1.1" distributed previously by
115 * him over the UNIX network Usenet.
116 * I also thank Chaim Benedelac (National Semiconductor),
117 * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
118 * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
119 * for their help with comments on earlier versions of the
122 * Changes: In the initialization part, this version follows mostly
123 * Rick Richardson's version distributed via Usenet, not the
124 * version distributed earlier via floppy disk by Reinhold Weicker.
125 * As a concession to older compilers, names have been made
126 * unique within the first 8 characters.
127 * Inside the measurement loop, this version follows the
128 * version previously distributed by Reinhold Weicker.
130 * At several places in the benchmark, code has been added,
131 * but within the measurement loop only in branches that
132 * are not executed. The intention is that optimizing compilers
133 * should be prevented from moving code out of the measurement
134 * loop, or from removing code altogether. Since the statements
135 * that are executed within the measurement loop have NOT been
136 * changed, the numbers defining the "Dhrystone distribution"
137 * (distribution of statements, operand types and locality)
138 * still hold. Except for sophisticated optimizing compilers,
139 * execution times for this version should be the same as
140 * for previous versions.
142 * Since it has proven difficult to subtract the time for the
143 * measurement loop overhead in a correct way, the loop check
144 * has been made a part of the benchmark. This does have
145 * an impact - though a very minor one - on the distribution
146 * statistics which have been updated for this version.
148 * All changes within the measurement loop are described
149 * and discussed in the companion paper "Rationale for
150 * Dhrystone version 2".
152 * Because of the self-imposed limitation that the order and
153 * distribution of the executed statements should not be
154 * changed, there are still cases where optimizing compilers
155 * may not generate code for some statements. To a certain
156 * degree, this is unavoidable for small synthetic benchmarks.
157 * Users of the benchmark are advised to check code listings
158 * whether code is generated for all statements of Dhrystone.
160 * Version 2.1 is identical to version 2.0 distributed via
161 * the UNIX network Usenet in March 1988 except that it corrects
162 * some minor deficiencies that were found by users of version 2.0.
163 * The only change within the measurement loop is that a
164 * non-executed "else" part was added to the "if" statement in
165 * Func_3, and a non-executed "else" part removed from Proc_3.
167 * Version C/2.2, Steven Pemberton, October 1993
168 * Functionally, identical to version 2.2; the changes are in
169 * how you compile and use it:
170 * - Everything is in one file now, but compiled in 2 passes
171 * - Compile (and run) by running the file through the shell: 'sh dhry.c"
172 * - Uses the system definition of HZ if one can be found
173 * - HZ must be defined, otherwise it won't compile (no defaults here)
174 * - The (uninteresting) output is printed to stderr (dhry2 > /dev/null)
175 * - The number of loops is passed as a parameter, rather than read
177 * - If the number of loops is insufficient to get a good result,
178 * it repeats it with loops*10 until it is enough (rather than just
180 * - Output says which sort of clock it is using, and the HZ value
181 * - You can use -DREG instead of the -DREG=register of previous versions
182 * - Some stylistic cleanups.
184 ***************************************************************************
186 * Compilation model and measurement (IMPORTANT):
188 * The following "ground rules" apply for measurements:
189 * - Separate compilation
190 * - No procedure merging
191 * - Otherwise, compiler optimizations are allowed but should be indicated
192 * - Default results are those without register declarations
193 * See the companion paper "Rationale for Dhrystone Version 2" for a more
194 * detailed discussion of these ground rules.
196 * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
197 * models ("small", "medium", "large" etc.) should be given if possible,
198 * together with a definition of these models for the compiler system used.
200 **************************************************************************
202 * Dhrystone (C version) statistics:
204 * [Comment from the first distribution, updated for version 2.
205 * Note that because of language differences, the numbers are slightly
206 * different from the Ada version.]
208 * The following program contains statements of a high level programming
209 * language (here: C) in a distribution considered representative:
211 * assignments 52 (51.0 %)
212 * control statements 33 (32.4 %)
213 * procedure, function calls 17 (16.7 %)
215 * 103 statements are dynamically executed. The program is balanced with
216 * respect to the three aspects:
221 * operand global, local, parameter, or constant.
223 * The combination of these three aspects is balanced only approximately.
226 * ----------------- number
234 * with record component
238 * X = Y +|-|"&&"|"|" Z 5
239 * X = Y +|-|"==" Constant 6
254 * for ... 7 | counted every time
255 * while ... 4 | the loop condition
256 * do ... while 1 | is evaluated
264 * P (...) procedure call 11
266 * library procedure 1
276 * The average number of parameters in procedure or function calls
277 * is 1.82 (not counting the function values aX *
302 * && (AND-THEN) 1 1.6
310 * 3. Operand Type (counted once per operand reference):
316 * Character 45 18.6 %
324 * When there is an access path leading to the final operand (e.g. a record
325 * component), only the final data type on the access path is counted.
328 * 4. Operand Locality:
329 * -------------------
333 * local variable 114 47.1 %
334 * global variable 22 9.1 %
335 * parameter 45 18.6 %
338 * function result 6 2.5 %
343 * The program does not compute anything meaningful, but it is syntactically
344 * and semantically correct. All variables have a value assigned to them
345 * before they are used as a source operand.
347 * There has been no explicit effort to account for the effects of a
348 * cache, or to balance the use of long or short displacements for code or
351 ***************************************************************************
354 /* Compiler and system dependent definitions: */
356 /* variables for time measurement: */
360 #define CLOCK_TYPE "time()"
362 #define HZ (1) /* time() returns time in seconds */
363 extern long time(); /* see library function "time" */
364 #define Too_Small_Time 2 /* Measurements should last at least 2 seconds */
365 #define Start_Timer() Begin_Time = time ( (long *) 0)
366 #define Stop_Timer() End_Time = time ( (long *) 0)
370 #ifdef MSC_CLOCK /* Use Microsoft C hi-res clock */
376 #define CLOCK_TYPE "MSC clock()"
377 extern clock_t clock();
378 #define Too_Small_Time (2*HZ)
379 #define Start_Timer() Begin_Time = clock()
380 #define Stop_Timer() End_Time = clock()
382 #elif defined(__riscv)
385 #define Too_Small_Time 1
386 #define CLOCK_TYPE "rdcycle()"
387 #define Start_Timer() Begin_Time = read_csr(mcycle)
388 #define Stop_Timer() End_Time = read_csr(mcycle)
391 /* Use times(2) time function unless */
392 /* explicitly defined otherwise */
393 #define CLOCK_TYPE "times()"
394 #include <sys/types.h>
395 #include <sys/times.h>
396 #ifndef HZ /* Added by SP 900619 */
397 #include <sys/param.h> /* If your system doesn't have this, use -DHZ=xxx */
399 *** You must define HZ
!!! ***
402 struct tms time_info
;
404 /*extern int times ();*/
405 /* see library function "times" */
406 #define Too_Small_Time (2*HZ)
407 /* Measurements should last at least about 2 seconds */
408 #define Start_Timer() times(&time_info); Begin_Time=(long)time_info.tms_utime
409 #define Stop_Timer() times(&time_info); End_Time = (long)time_info.tms_utime
411 #endif /* MSC_CLOCK */
415 #define Mic_secs_Per_Second 1000000
416 #define NUMBER_OF_RUNS 500 /* Default number of runs */
418 #ifdef NOSTRUCTASSIGN
419 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
421 #define structassign(d, s) d = s
430 typedef int Enumeration
;
432 typedef enum {Ident_1
, Ident_2
, Ident_3
, Ident_4
, Ident_5
}
435 /* for boolean and enumeration types in Ada, Pascal */
437 /* General definitions: */
441 /* for strcpy, strcmp */
444 /* Value of a Null pointer */
448 typedef int One_Thirty
;
449 typedef int One_Fifty
;
450 typedef char Capital_Letter
;
452 typedef char Str_30
[31];
453 typedef int Arr_1_Dim
[50];
454 typedef int Arr_2_Dim
[50] [50];
456 typedef struct record
458 struct record
*Ptr_Comp
;
462 Enumeration Enum_Comp
;
467 Enumeration E_Comp_2
;
468 char Str_2_Comp
[31];
475 } Rec_Type
, *Rec_Pointer
;