00001 /* 00002 **************************************************************************** 00003 * 00004 * "DHRYSTONE" Benchmark Program 00005 * ----------------------------- 00006 * 00007 * Version: C, Version 2.1 00008 * 00009 * File: dhry.h (part 1 of 3) 00010 * 00011 * Date: May 25, 1988 00012 * 00013 * Author: Reinhold P. Weicker 00014 * Siemens AG, E STE 35 00015 * Postfach 3240 00016 * 8520 Erlangen 00017 * Germany (West) 00018 * Phone: [xxx-49]-9131-7-20330 00019 * (8-17 Central European Time) 00020 * Usenet: ..!mcvax!unido!estevax!weicker 00021 * 00022 * Original Version (in Ada) published in 00023 * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), 00024 * pp. 1013 - 1030, together with the statistics 00025 * on which the distribution of statements etc. is based. 00026 * 00027 * In this C version, the following C library functions are used: 00028 * - strcpy, strcmp (inside the measurement loop) 00029 * - printf, scanf (outside the measurement loop) 00030 * In addition, Berkeley UNIX system calls "times ()" or "time ()" 00031 * are used for execution time measurement. For measurements 00032 * on other systems, these calls have to be changed. 00033 * 00034 * Collection of Results: 00035 * Reinhold Weicker (address see above) and 00036 * 00037 * Rick Richardson 00038 * PC Research. Inc. 00039 * 94 Apple Orchard Drive 00040 * Tinton Falls, NJ 07724 00041 * Phone: (201) 389-8963 (9-17 EST) 00042 * Usenet: ...!uunet!pcrat!rick 00043 * 00044 * Please send results to Rick Richardson and/or Reinhold Weicker. 00045 * Complete information should be given on hardware and software used. 00046 * Hardware information includes: Machine type, CPU, type and size 00047 * of caches; for microprocessors: clock frequency, memory speed 00048 * (number of wait states). 00049 * Software information includes: Compiler (and runtime library) 00050 * manufacturer and version, compilation switches, OS version. 00051 * The Operating System version may give an indication about the 00052 * compiler; Dhrystone itself performs no OS calls in the measurement loop. 00053 * 00054 * The complete output generated by the program should be mailed 00055 * such that at least some checks for correctness can be made. 00056 * 00057 *************************************************************************** 00058 * 00059 * History: This version C/2.1 has been made for two reasons: 00060 * 00061 * 1) There is an obvious need for a common C version of 00062 * Dhrystone, since C is at present the most popular system 00063 * programming language for the class of processors 00064 * (microcomputers, minicomputers) where Dhrystone is used most. 00065 * There should be, as far as possible, only one C version of 00066 * Dhrystone such that results can be compared without 00067 * restrictions. In the past, the C versions distributed 00068 * by Rick Richardson (Version 1.1) and by Reinhold Weicker 00069 * had small (though not significant) differences. 00070 * 00071 * 2) As far as it is possible without changes to the Dhrystone 00072 * statistics, optimizing compilers should be prevented from 00073 * removing significant statements. 00074 * 00075 * This C version has been developed in cooperation with 00076 * Rick Richardson (Tinton Falls, NJ), it incorporates many 00077 * ideas from the "Version 1.1" distributed previously by 00078 * him over the UNIX network Usenet. 00079 * I also thank Chaim Benedelac (National Semiconductor), 00080 * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), 00081 * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) 00082 * for their help with comments on earlier versions of the 00083 * benchmark. 00084 * 00085 * Changes: In the initialization part, this version follows mostly 00086 * Rick Richardson's version distributed via Usenet, not the 00087 * version distributed earlier via floppy disk by Reinhold Weicker. 00088 * As a concession to older compilers, names have been made 00089 * unique within the first 8 characters. 00090 * Inside the measurement loop, this version follows the 00091 * version previously distributed by Reinhold Weicker. 00092 * 00093 * At several places in the benchmark, code has been added, 00094 * but within the measurement loop only in branches that 00095 * are not executed. The intention is that optimizing compilers 00096 * should be prevented from moving code out of the measurement 00097 * loop, or from removing code altogether. Since the statements 00098 * that are executed within the measurement loop have NOT been 00099 * changed, the numbers defining the "Dhrystone distribution" 00100 * (distribution of statements, operand types and locality) 00101 * still hold. Except for sophisticated optimizing compilers, 00102 * execution times for this version should be the same as 00103 * for previous versions. 00104 * 00105 * Since it has proven difficult to subtract the time for the 00106 * measurement loop overhead in a correct way, the loop check 00107 * has been made a part of the benchmark. This does have 00108 * an impact - though a very minor one - on the distribution 00109 * statistics which have been updated for this version. 00110 * 00111 * All changes within the measurement loop are described 00112 * and discussed in the companion paper "Rationale for 00113 * Dhrystone version 2". 00114 * 00115 * Because of the self-imposed limitation that the order and 00116 * distribution of the executed statements should not be 00117 * changed, there are still cases where optimizing compilers 00118 * may not generate code for some statements. To a certain 00119 * degree, this is unavoidable for small synthetic benchmarks. 00120 * Users of the benchmark are advised to check code listings 00121 * whether code is generated for all statements of Dhrystone. 00122 * 00123 * Version 2.1 is identical to version 2.0 distributed via 00124 * the UNIX network Usenet in March 1988 except that it corrects 00125 * some minor deficiencies that were found by users of version 2.0. 00126 * The only change within the measurement loop is that a 00127 * non-executed "else" part was added to the "if" statement in 00128 * Func_3, and a non-executed "else" part removed from Proc_3. 00129 * 00130 *************************************************************************** 00131 * 00132 * Defines: The following "Defines" are possible: 00133 * -DREG=register (default: Not defined) 00134 * As an approximation to what an average C programmer 00135 * might do, the "register" storage class is applied 00136 * (if enabled by -DREG=register) 00137 * - for local variables, if they are used (dynamically) 00138 * five or more times 00139 * - for parameters if they are used (dynamically) 00140 * six or more times 00141 * Note that an optimal "register" strategy is 00142 * compiler-dependent, and that "register" declarations 00143 * do not necessarily lead to faster execution. 00144 * -DNOSTRUCTASSIGN (default: Not defined) 00145 * Define if the C compiler does not support 00146 * assignment of structures. 00147 * -DNOENUMS (default: Not defined) 00148 * Define if the C compiler does not support 00149 * enumeration types. 00150 * -DTIMES (default) 00151 * -DTIME 00152 * The "times" function of UNIX (returning process times) 00153 * or the "time" function (returning wallclock time) 00154 * is used for measurement. 00155 * For single user machines, "time ()" is adequate. For 00156 * multi-user machines where you cannot get single-user 00157 * access, use the "times ()" function. If you have 00158 * neither, use a stopwatch in the dead of night. 00159 * "printf"s are provided marking the points "Start Timer" 00160 * and "Stop Timer". DO NOT use the UNIX "time(1)" 00161 * command, as this will measure the total time to 00162 * run this program, which will (erroneously) include 00163 * the time to allocate storage (malloc) and to perform 00164 * the initialization. 00165 * -DHZ=nnn 00166 * In Berkeley UNIX, the function "times" returns process 00167 * time in 1/HZ seconds, with HZ = 60 for most systems. 00168 * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY 00169 * A VALUE. 00170 * 00171 *************************************************************************** 00172 * 00173 * Compilation model and measurement (IMPORTANT): 00174 * 00175 * This C version of Dhrystone consists of three files: 00176 * - dhry.h (this file, containing global definitions and comments) 00177 * - dhry_1.c (containing the code corresponding to Ada package Pack_1) 00178 * - dhry_2.c (containing the code corresponding to Ada package Pack_2) 00179 * 00180 * The following "ground rules" apply for measurements: 00181 * - Separate compilation 00182 * - No procedure merging 00183 * - Otherwise, compiler optimizations are allowed but should be indicated 00184 * - Default results are those without register declarations 00185 * See the companion paper "Rationale for Dhrystone Version 2" for a more 00186 * detailed discussion of these ground rules. 00187 * 00188 * For 16-Bit processors (e.g. 80186, 80286), times for all compilation 00189 * models ("small", "medium", "large" etc.) should be given if possible, 00190 * together with a definition of these models for the compiler system used. 00191 * 00192 ************************************************************************** 00193 * 00194 * Dhrystone (C version) statistics: 00195 * 00196 * [Comment from the first distribution, updated for version 2. 00197 * Note that because of language differences, the numbers are slightly 00198 * different from the Ada version.] 00199 * 00200 * The following program contains statements of a high level programming 00201 * language (here: C) in a distribution considered representative: 00202 * 00203 * assignments 52 (51.0 %) 00204 * control statements 33 (32.4 %) 00205 * procedure, function calls 17 (16.7 %) 00206 * 00207 * 103 statements are dynamically executed. The program is balanced with 00208 * respect to the three aspects: 00209 * 00210 * - statement type 00211 * - operand type 00212 * - operand locality 00213 * operand global, local, parameter, or constant. 00214 * 00215 * The combination of these three aspects is balanced only approximately. 00216 * 00217 * 1. Statement Type: 00218 * ----------------- number 00219 * 00220 * V1 = V2 9 00221 * (incl. V1 = F(..) 00222 * V = Constant 12 00223 * Assignment, 7 00224 * with array element 00225 * Assignment, 6 00226 * with record component 00227 * -- 00228 * 34 34 00229 * 00230 * X = Y +|-|"&&"|"|" Z 5 00231 * X = Y +|-|"==" Constant 6 00232 * X = X +|- 1 3 00233 * X = Y *|/ Z 2 00234 * X = Expression, 1 00235 * two operators 00236 * X = Expression, 1 00237 * three operators 00238 * -- 00239 * 18 18 00240 * 00241 * if .... 14 00242 * with "else" 7 00243 * without "else" 7 00244 * executed 3 00245 * not executed 4 00246 * for ... 7 | counted every time 00247 * while ... 4 | the loop condition 00248 * do ... while 1 | is evaluated 00249 * switch ... 1 00250 * break 1 00251 * declaration with 1 00252 * initialization 00253 * -- 00254 * 34 34 00255 * 00256 * P (...) procedure call 11 00257 * user procedure 10 00258 * library procedure 1 00259 * X = F (...) 00260 * function call 6 00261 * user function 5 00262 * library function 1 00263 * -- 00264 * 17 17 00265 * --- 00266 * 103 00267 * 00268 * The average number of parameters in procedure or function calls 00269 * is 1.82 (not counting the function values as implicit parameters). 00270 * 00271 * 00272 * 2. Operators 00273 * ------------ 00274 * number approximate 00275 * percentage 00276 * 00277 * Arithmetic 32 50.8 00278 * 00279 * + 21 33.3 00280 * - 7 11.1 00281 * * 3 4.8 00282 * / (int div) 1 1.6 00283 * 00284 * Comparison 27 42.8 00285 * 00286 * == 9 14.3 00287 * /= 4 6.3 00288 * > 1 1.6 00289 * < 3 4.8 00290 * >= 1 1.6 00291 * <= 9 14.3 00292 * 00293 * Logic 4 6.3 00294 * 00295 * && (AND-THEN) 1 1.6 00296 * | (OR) 1 1.6 00297 * ! (NOT) 2 3.2 00298 * 00299 * -- ----- 00300 * 63 100.1 00301 * 00302 * 00303 * 3. Operand Type (counted once per operand reference): 00304 * --------------- 00305 * number approximate 00306 * percentage 00307 * 00308 * Integer 175 72.3 % 00309 * Character 45 18.6 % 00310 * Pointer 12 5.0 % 00311 * String30 6 2.5 % 00312 * Array 2 0.8 % 00313 * Record 2 0.8 % 00314 * --- ------- 00315 * 242 100.0 % 00316 * 00317 * When there is an access path leading to the final operand (e.g. a record 00318 * component), only the final data type on the access path is counted. 00319 * 00320 * 00321 * 4. Operand Locality: 00322 * ------------------- 00323 * number approximate 00324 * percentage 00325 * 00326 * local variable 114 47.1 % 00327 * global variable 22 9.1 % 00328 * parameter 45 18.6 % 00329 * value 23 9.5 % 00330 * reference 22 9.1 % 00331 * function result 6 2.5 % 00332 * constant 55 22.7 % 00333 * --- ------- 00334 * 242 100.0 % 00335 * 00336 * 00337 * The program does not compute anything meaningful, but it is syntactically 00338 * and semantically correct. All variables have a value assigned to them 00339 * before they are used as a source operand. 00340 * 00341 * There has been no explicit effort to account for the effects of a 00342 * cache, or to balance the use of long or short displacements for code or 00343 * data. 00344 * 00345 *************************************************************************** 00346 */ 00347 00348 /* Compiler and system dependent definitions: */ 00349 00350 #ifndef TIME 00351 #undef TIMES 00352 #define TIMES 00353 #endif 00354 /* Use times(2) time function unless */ 00355 /* explicitly defined otherwise */ 00356 #define MSC_CLOCK 00357 00358 #ifdef MSC_CLOCK 00359 #undef HZ 00360 #undef TIMES 00361 #include <time.h> 00362 #define HZ CLK_TCK 00363 #endif 00364 /* Use Microsoft C hi-res clock */ 00365 00366 #ifdef TIMES 00367 #include <sys/types.h> 00368 #include <sys/times.h> 00369 /* for "times" */ 00370 #endif 00371 00372 #define Mic_secs_Per_Second 1000000.0 00373 /* Berkeley UNIX C returns process times in seconds/HZ */ 00374 00375 #ifdef NOSTRUCTASSIGN 00376 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) 00377 #else 00378 #define structassign(d, s) d = s 00379 #endif 00380 00381 #ifdef NOENUM 00382 #define Ident_1 0 00383 #define Ident_2 1 00384 #define Ident_3 2 00385 #define Ident_4 3 00386 #define Ident_5 4 00387 typedef int Enumeration; 00388 #else 00389 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} 00390 Enumeration; 00391 #endif 00392 /* for boolean and enumeration types in Ada, Pascal */ 00393 00394 /* General definitions: */ 00395 00396 #include <stdio.h> 00397 /* for strcpy, strcmp */ 00398 00399 #define Null 0 00400 /* Value of a Null pointer */ 00401 #define true 1 00402 #define false 0 00403 00404 typedef int One_Thirty; 00405 typedef int One_Fifty; 00406 typedef char Capital_Letter; 00407 typedef int Boolean; 00408 typedef char Str_30 [31]; 00409 typedef int Arr_1_Dim [50]; 00410 typedef int Arr_2_Dim [50] [50]; 00411 00412 typedef struct record 00413 { 00414 struct record *Ptr_Comp; 00415 Enumeration Discr; 00416 union { 00417 struct { 00418 Enumeration Enum_Comp; 00419 int Int_Comp; 00420 char Str_Comp [31]; 00421 } var_1; 00422 struct { 00423 Enumeration E_Comp_2; 00424 char Str_2_Comp [31]; 00425 } var_2; 00426 struct { 00427 char Ch_1_Comp; 00428 char Ch_2_Comp; 00429 } var_3; 00430 } variant; 00431 } Rec_Type, *Rec_Pointer; 00432