1 /* 2 **************************************************************************** 3 * 4 * "DHRYSTONE" Benchmark Program 5 * ----------------------------- 6 * 7 * Version: C, Version 2.1 8 * 9 * File: dhry.h (part 1 of 3) 10 * 11 * Date: May 17, 1988 12 * 13 * Author: Reinhold P. Weicker 14 * Siemens AG, E STE 35 15 * Postfach 3240 16 * 8520 Erlangen 17 * Germany (West) 18 * Phone: [xxx-49]-9131-7-20330 19 * (8-17 Central European Time) 20 * Usenet: ..!mcvax!unido!estevax!weicker 21 * 22 * Original Version (in Ada) published in 23 * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), 24 * pp. 1013 - 1030, together with the statistics 25 * on which the distribution of statements etc. is based. 26 * 27 * In this C version, the following C library functions are used: 28 * - strcpy, strcmp (inside the measurement loop) 29 * - printf, scanf (outside the measurement loop) 30 * In addition, Berkeley UNIX system calls "times ()" or "time ()" 31 * are used for execution time measurement. For measurements 32 * on other systems, these calls have to be changed. 33 * 34 * Collection of Results: 35 * Reinhold Weicker (address see above) and 36 * 37 * Rick Richardson 38 * PC Research. Inc. 39 * 94 Apple Orchard Drive 40 * Tinton Falls, NJ 07724 41 * Phone: (201) 389-8963 (9-17 EST) 42 * Usenet: ...!uunet!pcrat!rick 43 * 44 * Please send results to Rick Richardson and/or Reinhold Weicker. 45 * Complete information should be given on hardware and software used. 46 * Hardware information includes: Machine type, CPU, type and size 47 * of caches; for microprocessors: clock frequency, memory speed 48 * (number of wait states). 49 * Software information includes: Compiler (and runtime library) 50 * manufacturer and version, compilation switches, OS version. 51 * The Operating System version may give an indication about the 52 * compiler; Dhrystone itself performs no OS calls in the measurement loop. 53 * 54 * The complete output generated by the program should be mailed 55 * such that at least some checks for correctness can be made. 56 * 57 *************************************************************************** 58 * 59 * History: This version C/2.1 has been made for two reasons: 60 * 61 * 1) There is an obvious need for a common C version of 62 * Dhrystone, since C is at present the most popular system 63 * programming language for the class of processors 64 * (microcomputers, minicomputers) where Dhrystone is used most. 65 * There should be, as far as possible, only one C version of 66 * Dhrystone such that results can be compared without 67 * restrictions. In the past, the C versions distributed 68 * by Rick Richardson (Version 1.1) and by Reinhold Weicker 69 * had small (though not significant) differences. 70 * 71 * 2) As far as it is possible without changes to the Dhrystone 72 * statistics, optimizing compilers should be prevented from 73 * removing significant statements. 74 * 75 * This C version has been developed in cooperation with 76 * Rick Richardson (Tinton Falls, NJ), it incorporates many 77 * ideas from the "Version 1.1" distributed previously by 78 * him over the UNIX network Usenet. 79 * I also thank Chaim Benedelac (National Semiconductor), 80 * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), 81 * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) 82 * for their help with comments on earlier versions of the 83 * benchmark. 84 * 85 * Changes: In the initialization part, this version follows mostly 86 * Rick Richardson's version distributed via Usenet, not the 87 * version distributed earlier via floppy disk by Reinhold Weicker. 88 * As a concession to older compilers, names have been made 89 * unique within the first 8 characters. 90 * Inside the measurement loop, this version follows the 91 * version previously distributed by Reinhold Weicker. 92 * 93 * At several places in the benchmark, code has been added, 94 * but within the measurement loop only in branches that 95 * are not executed. The intention is that optimizing compilers 96 * should be prevented from moving code out of the measurement 97 * loop, or from removing code altogether. Since the statements 98 * that are executed within the measurement loop have NOT been 99 * changed, the numbers defining the "Dhrystone distribution" 100 * (distribution of statements, operand types and locality) 101 * still hold. Except for sophisticated optimizing compilers, 102 * execution times for this version should be the same as 103 * for previous versions. 104 * 105 * Since it has proven difficult to subtract the time for the 106 * measurement loop overhead in a correct way, the loop check 107 * has been made a part of the benchmark. This does have 108 * an impact - though a very minor one - on the distribution 109 * statistics which have been updated for this version. 110 * 111 * All changes within the measurement loop are described 112 * and discussed in the companion paper "Rationale for 113 * Dhrystone version 2". 114 * 115 * Because of the self-imposed limitation that the order and 116 * distribution of the executed statements should not be 117 * changed, there are still cases where optimizing compilers 118 * may not generate code for some statements. To a certain 119 * degree, this is unavoidable for small synthetic benchmarks. 120 * Users of the benchmark are advised to check code listings 121 * whether code is generated for all statements of Dhrystone. 122 * 123 * Version 2.1 is identical to version 2.0 distributed via 124 * the UNIX network Usenet in March 1988 except that it corrects 125 * some minor deficiencies that were found by users of version 2.0. 126 * The following corrections have been made in the C version: 127 * - The assignment to Number_Of_Runs was changed 128 * - The constant Too_Small_Time was changed 129 * - An "else" part was added to the "if" statement in Func_3; 130 * for compensation, an "else" part was removed in Proc_3 131 * - Shorter file names are used 132 * 133 *************************************************************************** 134 * 135 * Defines: The following "Defines" are possible: 136 * -DREG=register (default: Not defined) 137 * As an approximation to what an average C programmer 138 * might do, the "register" storage class is applied 139 * (if enabled by -DREG=register) 140 * - for local variables, if they are used (dynamically) 141 * five or more times 142 * - for parameters if they are used (dynamically) 143 * six or more times 144 * Note that an optimal "register" strategy is 145 * compiler-dependent, and that "register" declarations 146 * do not necessarily lead to faster execution. 147 * -DNOSTRUCTASSIGN (default: Not defined) 148 * Define if the C compiler does not support 149 * assignment of structures. 150 * -DNOENUMS (default: Not defined) 151 * Define if the C compiler does not support 152 * enumeration types. 153 * -DTIMES (default) 154 * -DTIME 155 * The "times" function of UNIX (returning process times) 156 * or the "time" function (returning wallclock time) 157 * is used for measurement. 158 * For single user machines, "time ()" is adequate. For 159 * multi-user machines where you cannot get single-user 160 * access, use the "times ()" function. If you have 161 * neither, use a stopwatch in the dead of night. 162 * "printf"s are provided marking the points "Start Timer" 163 * and "Stop Timer". DO NOT use the UNIX "time(1)" 164 * command, as this will measure the total time to 165 * run this program, which will (erroneously) include 166 * the time to allocate storage (malloc) and to perform 167 * the initialization. 168 * -DHZ=nnn 169 * In Berkeley UNIX, the function "times" returns process 170 * time in 1/HZ seconds, with HZ = 60 for most systems. 171 * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY 172 * A VALUE. 173 * 174 *************************************************************************** 175 * 176 * Compilation model and measurement (IMPORTANT): 177 * 178 * This C version of Dhrystone consists of three files: 179 * - dhry.h (this file, containing global definitions and comments) 180 * - dhry_1.c (containing the code corresponding to Ada package Pack_1) 181 * - dhry_2.c (containing the code corresponding to Ada package Pack_2) 182 * 183 * The following "ground rules" apply for measurements: 184 * - Separate compilation 185 * - No procedure merging 186 * - Otherwise, compiler optimizations are allowed but should be indicated 187 * - Default results are those without register declarations 188 * See the companion paper "Rationale for Dhrystone Version 2" for a more 189 * detailed discussion of these ground rules. 190 * 191 * For 16-Bit processors (e.g. 80186, 80286), times for all compilation 192 * models ("small", "medium", "large" etc.) should be given if possible, 193 * together with a definition of these models for the compiler system used. 194 * 195 ************************************************************************** 196 * 197 * Dhrystone (C version) statistics: 198 * 199 * [Comment from the first distribution, updated for version 2. 200 * Note that because of language differences, the numbers are slightly 201 * different from the Ada version.] 202 * 203 * The following program contains statements of a high level programming 204 * language (here: C) in a distribution considered representative: 205 * 206 * assignments 52 (51.0 %) 207 * control statements 33 (32.4 %) 208 * procedure, function calls 17 (16.7 %) 209 * 210 * 103 statements are dynamically executed. The program is balanced with 211 * respect to the three aspects: 212 * 213 * - statement type 214 * - operand type 215 * - operand locality 216 * operand global, local, parameter, or constant. 217 * 218 * The combination of these three aspects is balanced only approximately. 219 * 220 * 1. Statement Type: 221 * ----------------- number 222 * 223 * V1 = V2 9 224 * (incl. V1 = F(..) 225 * V = Constant 12 226 * Assignment, 7 227 * with array element 228 * Assignment, 6 229 * with record component 230 * -- 231 * 34 34 232 * 233 * X = Y +|-|"&&"|"|" Z 5 234 * X = Y +|-|"==" Constant 6 235 * X = X +|- 1 3 236 * X = Y *|/ Z 2 237 * X = Expression, 1 238 * two operators 239 * X = Expression, 1 240 * three operators 241 * -- 242 * 18 18 243 * 244 * if .... 14 245 * with "else" 7 246 * without "else" 7 247 * executed 3 248 * not executed 4 249 * for ... 7 | counted every time 250 * while ... 4 | the loop condition 251 * do ... while 1 | is evaluated 252 * switch ... 1 253 * break 1 254 * declaration with 1 255 * initialization 256 * -- 257 * 34 34 258 * 259 * P (...) procedure call 11 260 * user procedure 10 261 * library procedure 1 262 * X = F (...) 263 * function call 6 264 * user function 5 265 * library function 1 266 * -- 267 * 17 17 268 * --- 269 * 103 270 * 271 * The average number of parameters in procedure or function calls 272 * is 1.82 (not counting the function values as implicit parameters). 273 * 274 * 275 * 2. Operators 276 * ------------ 277 * number approximate 278 * percentage 279 * 280 * Arithmetic 32 50.8 281 * 282 * + 21 33.3 283 * - 7 11.1 284 * * 3 4.8 285 * / (int div) 1 1.6 286 * 287 * Comparison 27 42.8 288 * 289 * == 9 14.3 290 * /= 4 6.3 291 * > 1 1.6 292 * < 3 4.8 293 * >= 1 1.6 294 * <= 9 14.3 295 * 296 * Logic 4 6.3 297 * 298 * && (AND-THEN) 1 1.6 299 * | (OR) 1 1.6 300 * ! (NOT) 2 3.2 301 * 302 * -- ----- 303 * 63 100.1 304 * 305 * 306 * 3. Operand Type (counted once per operand reference): 307 * --------------- 308 * number approximate 309 * percentage 310 * 311 * Integer 175 72.3 % 312 * Character 45 18.6 % 313 * Pointer 12 5.0 % 314 * String30 6 2.5 % 315 * Array 2 0.8 % 316 * Record 2 0.8 % 317 * --- ------- 318 * 242 100.0 % 319 * 320 * When there is an access path leading to the final operand (e.g. a record 321 * component), only the final data type on the access path is counted. 322 * 323 * 324 * 4. Operand Locality: 325 * ------------------- 326 * number approximate 327 * percentage 328 * 329 * local variable 114 47.1 % 330 * global variable 22 9.1 % 331 * parameter 45 18.6 % 332 * value 23 9.5 % 333 * reference 22 9.1 % 334 * function result 6 2.5 % 335 * constant 55 22.7 % 336 * --- ------- 337 * 242 100.0 % 338 * 339 * 340 * The program does not compute anything meaningful, but it is syntactically 341 * and semantically correct. All variables have a value assigned to them 342 * before they are used as a source operand. 343 * 344 * There has been no explicit effort to account for the effects of a 345 * cache, or to balance the use of long or short displacements for code or 346 * data. 347 * 348 *************************************************************************** 349 */ 350 351 /* Compiler and system dependent definitions: */ 352 353 #ifndef TIME 354 #ifndef TIMES 355 #define TIMES 356 #endif 357 #endif 358 /* Use times(2) time function unless */ 359 /* explicitly defined otherwise */ 360 361 #ifdef MSC_CLOCK 362 #undef HZ 363 #undef TIMES 364 #include <time.h> 365 #define HZ CLK_TCK 366 #endif 367 /* Use Microsoft C hi-res clock */ 368 369 #ifdef TIMES 370 #include <sys/types.h> 371 #include <sys/times.h> 372 /* for "times" */ 373 #endif 374 375 #define Mic_secs_Per_Second 1000000.0 376 /* Berkeley UNIX C returns process times in seconds/HZ */ 377 378 #ifdef NOSTRUCTASSIGN 379 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) 380 #else 381 #define structassign(d, s) d = s 382 #endif 383 384 #ifdef NOENUM 385 #define Ident_1 0 386 #define Ident_2 1 387 #define Ident_3 2 388 #define Ident_4 3 389 #define Ident_5 4 390 typedef int Enumeration; 391 #else 392 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} 393 Enumeration; 394 #endif 395 /* for boolean and enumeration types in Ada, Pascal */ 396 397 /* General definitions: */ 398 399 #include <stdio.h> 400 /* for strcpy, strcmp */ 401 402 #define Null 0 403 /* Value of a Null pointer */ 404 #define true 1 405 #define false 0 406 407 typedef int One_Thirty; 408 typedef int One_Fifty; 409 typedef char Capital_Letter; 410 typedef int Boolean; 411 typedef char Str_30 [31]; 412 typedef int Arr_1_Dim [50]; 413 typedef int Arr_2_Dim [50] [50]; 414 415 typedef struct record 416 { 417 struct record *Ptr_Comp; 418 Enumeration Discr; 419 union { 420 struct { 421 Enumeration Enum_Comp; 422 int Int_Comp; 423 char Str_Comp [31]; 424 } var_1; 425 struct { 426 Enumeration E_Comp_2; 427 char Str_2_Comp [31]; 428 } var_2; 429 struct { 430 char Ch_1_Comp; 431 char Ch_2_Comp; 432 } var_3; 433 } variant; 434 } Rec_Type, *Rec_Pointer; 435 436 437