Source: ERCC08:DRY.DHRY1#C Compiled: 25/04/89 16.53.22 Object: ERCC08:DRY.DHRY1#O Parms set: OPT 0 /* 1 **************************************************************************** 2 * 3 * "DHRYSTONE" Benchmark Program 4 * ----------------------------- 5 * 6 * Version: C, Version 2.1 7 * 8 * File: dhry_1.c (part 2 of 3) 9 * 10 * Date: May 25, 1988 11 * 12 * Author: Reinhold P. Weicker 13 * 14 **************************************************************************** 15 */ 16 17 *&*&nclude dhry#h*/ 18 /* jm */ 19 #define TIME 20 #define HZ 50 21 /* jm */ 22 23 /* 24 **************************************************************************** 25 * 26 * "DHRYSTONE" Benchmark Program 27 * ----------------------------- 28 * 29 * Version: C, Version 2.1 30 * 31 * File: dhry.h (part 1 of 3) 32 * 33 * Date: May 25, 1988 34 * 35 * Author: Reinhold P. Weicker 36 * Siemens AG, E STE 35 37 * Postfach 3240 38 * 8520 Erlangen 39 * Germany (West) 40 * Phone: [xxx-49]-9131-7-20330 41 * (8-17 Central European Time) 42 * Usenet: ..!mcvax!unido!estevax!weicker 43 * 44 * Original Version (in Ada) published in 45 * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), 46 * pp. 1013 - 1030, together with the statistics 47 * on which the distribution of statements etc. is based. 48 * 49 * In this C version, the following C library functions are used: 50 * - strcpy, strcmp (inside the measurement loop) 51 * - printf, scanf (outside the measurement loop) 52 * In addition, Berkeley UNIX system calls "times ()" or "time ()" 53 * are used for execution time measurement. For measurements 54 * on other systems, these calls have to be changed. 55 * 56 * Collection of Results: 57 * Reinhold Weicker (address see above) and 58 * 59 * Rick Richardson 60 * PC Research. Inc. 61 * 94 Apple Orchard Drive 62 * Tinton Falls, NJ 07724 63 * Phone: (201) 389-8963 (9-17 EST) 64 * Usenet: ...!uunet!pcrat!rick 65 * 66 * Please send results to Rick Richardson and/or Reinhold Weicker. 67 * Complete information should be given on hardware and software used. 68 * Hardware information includes: Machine type, CPU, type and size 69 * of caches; for microprocessors: clock frequency, memory speed 70 * (number of wait states). 71 * Software information includes: Compiler (and runtime library) 72 * manufacturer and version, compilation switches, OS version. 73 * The Operating System version may give an indication about the 74 * compiler; Dhrystone itself performs no OS calls in the measurement loop. 75 * 76 * The complete output generated by the program should be mailed 77 * such that at least some checks for correctness can be made. 78 * 79 *************************************************************************** 80 * 81 * History: This version C/2.1 has been made for two reasons: 82 * 83 * 1) There is an obvious need for a common C version of 84 * Dhrystone, since C is at present the most popular system 85 * programming language for the class of processors 86 * (microcomputers, minicomputers) where Dhrystone is used most. 87 * There should be, as far as possible, only one C version of 88 * Dhrystone such that results can be compared without 89 * restrictions. In the past, the C versions distributed 90 * by Rick Richardson (Version 1.1) and by Reinhold Weicker 91 * had small (though not significant) differences. 92 * 93 * 2) As far as it is possible without changes to the Dhrystone 94 * statistics, optimizing compilers should be prevented from 95 * removing significant statements. 96 * 97 * This C version has been developed in cooperation with 98 * Rick Richardson (Tinton Falls, NJ), it incorporates many 99 * ideas from the "Version 1.1" distributed previously by 100 * him over the UNIX network Usenet. 101 * I also thank Chaim Benedelac (National Semiconductor), 102 * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), 103 * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) 104 * for their help with comments on earlier versions of the 105 * benchmark. 106 * 107 * Changes: In the initialization part, this version follows mostly 108 * Rick Richardson's version distributed via Usenet, not the 109 * version distributed earlier via floppy disk by Reinhold Weicker. 110 * As a concession to older compilers, names have been made 111 * unique within the first 8 characters. 112 * Inside the measurement loop, this version follows the 113 * version previously distributed by Reinhold Weicker. 114 * 115 * At several places in the benchmark, code has been added, 116 * but within the measurement loop only in branches that 117 * are not executed. The intention is that optimizing compilers 118 * should be prevented from moving code out of the measurement 119 * loop, or from removing code altogether. Since the statements 120 * that are executed within the measurement loop have NOT been 121 * changed, the numbers defining the "Dhrystone distribution" 122 * (distribution of statements, operand types and locality) 123 * still hold. Except for sophisticated optimizing compilers, 124 * execution times for this version should be the same as 125 * for previous versions. 126 * 127 * Since it has proven difficult to subtract the time for the 128 * measurement loop overhead in a correct way, the loop check 129 * has been made a part of the benchmark. This does have 130 * an impact - though a very minor one - on the distribution 131 * statistics which have been updated for this version. 132 * 133 * All changes within the measurement loop are described 134 * and discussed in the companion paper "Rationale for 135 * Dhrystone version 2". 136 * 137 * Because of the self-imposed limitation that the order and 138 * distribution of the executed statements should not be 139 * changed, there are still cases where optimizing compilers 140 * may not generate code for some statements. To a certain 141 * degree, this is unavoidable for small synthetic benchmarks. 142 * Users of the benchmark are advised to check code listings 143 * whether code is generated for all statements of Dhrystone. 144 * 145 * Version 2.1 is identical to version 2.0 distributed via 146 * the UNIX network Usenet in March 1988 except that it corrects 147 * some minor deficiencies that were found by users of version 2.0. 148 * The only change within the measurement loop is that a 149 * non-executed "else" part was added to the "if" statement in 150 * Func_3, and a non-executed "else" part removed from Proc_3. 151 * 152 *************************************************************************** 153 * 154 * Defines: The following "Defines" are possible: 155 * -DREG=register (default: Not defined) 156 * As an approximation to what an average C programmer 157 * might do, the "register" storage class is applied 158 * (if enabled by -DREG=register) 159 * - for local variables, if they are used (dynamically) 160 * five or more times 161 * - for parameters if they are used (dynamically) 162 * six or more times 163 * Note that an optimal "register" strategy is 164 * compiler-dependent, and that "register" declarations 165 * do not necessarily lead to faster execution. 166 * -DNOSTRUCTASSIGN (default: Not defined) 167 * Define if the C compiler does not support 168 * assignment of structures. 169 * -DNOENUMS (default: Not defined) 170 * Define if the C compiler does not support 171 * enumeration types. 172 * -DTIMES (default) 173 * -DTIME 174 * The "times" function of UNIX (returning process times) 175 * or the "time" function (returning wallclock time) 176 * is used for measurement. 177 * For single user machines, "time ()" is adequate. For 178 * multi-user machines where you cannot get single-user 179 * access, use the "times ()" function. If you have 180 * neither, use a stopwatch in the dead of night. 181 * "printf"s are provided marking the points "Start Timer" 182 * and "Stop Timer". DO NOT use the UNIX "time(1)" 183 * command, as this will measure the total time to 184 * run this program, which will (erroneously) include 185 * the time to allocate storage (malloc) and to perform 186 * the initialization. 187 * -DHZ=nnn 188 * In Berkeley UNIX, the function "times" returns process 189 * time in 1/HZ seconds, with HZ = 60 for most systems. 190 * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY 191 * A VALUE. 192 * 193 *************************************************************************** 194 * 195 * Compilation model and measurement (IMPORTANT): 196 * 197 * This C version of Dhrystone consists of three files: 198 * - dhry.h (this file, containing global definitions and comments) 199 * - dhry_1.c (containing the code corresponding to Ada package Pack_1) 200 * - dhry_2.c (containing the code corresponding to Ada package Pack_2) 201 * 202 * The following "ground rules" apply for measurements: 203 * - Separate compilation 204 * - No procedure merging 205 * - Otherwise, compiler optimizations are allowed but should be indicated 206 * - Default results are those without register declarations 207 * See the companion paper "Rationale for Dhrystone Version 2" for a more 208 * detailed discussion of these ground rules. 209 * 210 * For 16-Bit processors (e.g. 80186, 80286), times for all compilation 211 * models ("small", "medium", "large" etc.) should be given if possible, 212 * together with a definition of these models for the compiler system used. 213 * 214 ************************************************************************** 215 * 216 * Dhrystone (C version) statistics: 217 * 218 * [Comment from the first distribution, updated for version 2. 219 * Note that because of language differences, the numbers are slightly 220 * different from the Ada version.] 221 * 222 * The following program contains statements of a high level programming 223 * language (here: C) in a distribution considered representative: 224 * 225 * assignments 52 (51.0 %) 226 * control statements 33 (32.4 %) 227 * procedure, function calls 17 (16.7 %) 228 * 229 * 103 statements are dynamically executed. The program is balanced with 230 * respect to the three aspects: 231 * 232 * - statement type 233 * - operand type 234 * - operand locality 235 * operand global, local, parameter, or constant. 236 * 237 * The combination of these three aspects is balanced only approximately. 238 * 239 * 1. Statement Type: 240 * ----------------- number 241 * 242 * V1 = V2 9 243 * (incl. V1 = F(..) 244 * V = Constant 12 245 * Assignment, 7 246 * with array element 247 * Assignment, 6 248 * with record component 249 * -- 250 * 34 34 251 * 252 * X = Y +|-|"&&"|"|" Z 5 253 * X = Y +|-|"==" Constant 6 254 * X = X +|- 1 3 255 * X = Y *|/ Z 2 256 * X = Expression, 1 257 * two operators 258 * X = Expression, 1 259 * three operators 260 * -- 261 * 18 18 262 * 263 * if .... 14 264 * with "else" 7 265 * without "else" 7 266 * executed 3 267 * not executed 4 268 * for ... 7 | counted every time 269 * while ... 4 | the loop condition 270 * do ... while 1 | is evaluated 271 * switch ... 1 272 * break 1 273 * declaration with 1 274 * initialization 275 * -- 276 * 34 34 277 * 278 * P (...) procedure call 11 279 * user procedure 10 280 * library procedure 1 281 * X = F (...) 282 * function call 6 283 * user function 5 284 * library function 1 285 * -- 286 * 17 17 287 * --- 288 * 103 289 * 290 * The average number of parameters in procedure or function calls 291 * is 1.82 (not counting the function values aX * 292 * 293 * 2. Operators 294 * ------------ 295 * number approximate 296 * percentage 297 * 298 * Arithmetic 32 50.8 299 * 300 * + 21 33.3 301 * - 7 11.1 302 * * 3 4.8 303 * / (int div) 1 1.6 304 * 305 * Comparison 27 42.8 306 * 307 * == 9 14.3 308 * /= 4 6.3 309 * > 1 1.6 310 * < 3 4.8 311 * >= 1 1.6 312 * <= 9 14.3 313 * 314 * Logic 4 6.3 315 * 316 * && (AND-THEN) 1 1.6 317 * | (OR) 1 1.6 318 * ! (NOT) 2 3.2 319 * 320 * -- ----- 321 * 63 100.1 322 * 323 * 324 * 3. Operand Type (counted once per operand reference): 325 * --------------- 326 * number approximate 327 * percentage 328 * 329 * Integer 175 72.3 % 330 * Character 45 18.6 % 331 * Pointer 12 5.0 % 332 * String30 6 2.5 % 333 * Array 2 0.8 % 334 * Record 2 0.8 % 335 * --- ------- 336 * 242 100.0 % 337 * 338 * When there is an access path leading to the final operand (e.g. a record 339 * component), only the final data type on the access path is counted. 340 * 341 * 342 * 4. Operand Locality: 343 * ------------------- 344 * number approximate 345 * percentage 346 * 347 * local variable 114 47.1 % 348 * global variable 22 9.1 % 349 * parameter 45 18.6 % 350 * value 23 9.5 % 351 * reference 22 9.1 % 352 * function result 6 2.5 % 353 * constant 55 22.7 % 354 * --- ------- 355 * 242 100.0 % 356 * 357 * 358 * The program does not compute anything meaningful, but it is syntactically 359 * and semantically correct. All variables have a value assigned to them 360 * before they are used as a source operand. 361 * 362 * There has been no explicit effort to account for the effects of a 363 * cache, or to balance the use of long or short displacements for code or 364 * data. 365 * 366 *************************************************************************** 367 */ 368 369 /* Compiler and system dependent definitions: */ 370 371 #ifndef TIME 372 #undef TIMES 373 #define TIMES 374 #endif 375 /* Use times(2) time function unless */ 376 /* explicitly defined otherwise */ 377 378 #ifdef MSC_CLOCK 379 #undef HZ 380 #undef TIMES 381 *&*&nclude subsys:cinserts_time*/ 382 /* ================================================================ */ 383 /* = EMAS C Header file = */ 384 /* = = */ 385 /* = time.h = */ 386 /* = = */ 387 /* = (C) Copyright EPCL 1987 = */ 388 /* ================================================================ */ 389 390 #define CLK_TCK 1.0 391 typedef double clock_t; 392 typedef double time_t; 393 struct tm{ 394 int tm_sec; 395 int tm_min; 396 int tm_hour; 397 int tm_mday; 398 int tm_mon; 399 int tm_year; 400 int tm_wday; 401 int tm_yday; 402 int tm_isdst; 403 }; 404 405 clock_t clock (); 406 time_t time (); 407 char *asctime (); 408 char *ctime (); 409 double difftime (); 410 struct tm *gmtime (); 411 struct tm *localtime (); 412 &*&*nd of include file */ 413 #define HZ CLK_TCK 414 #endif 415 /* Use Microsoft C hi-res clock */ 416 417 #ifdef TIMES ** WARNING ** Include file subsys:cinserts_sys/types does not exist 418 /*#include subsys:cinserts_sys/types*/ ** WARNING ** Include file subsys:cinserts_sys/times does not exist 419 /*#include subsys:cinserts_sys/times*/ 420 /* for "times" */ 421 #endif 422 423 #define Mic_secs_Per_Second 1000000.0 424 /* Berkeley UNIX C returns process times in seconds/HZ */ 425 426 #ifdef NOSTRUCTASSIGN 427 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) 428 #else 429 #define structassign(d, s) d = s 430 #endif 431 432 #ifdef NOENUM 433 #define Ident_1 0 434 #define Ident_2 1 435 #define Ident_3 2 436 #define Ident_4 3 437 #define Ident_5 4 438 typedef int Enumeration; 439 #else 440 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} 441 Enumeration; 442 #endif 443 /* for boolean and enumeration types in Ada, Pascal */ 444 445 /* General definitions: */ 446 447 *&*&nclude subsys:cinserts_stdio*/ 448 /* ================================================================ */ 449 /* = EMAS C Header file = */ 450 /* = = */ 451 /* = stdio.h = */ 452 /* = = */ 453 /* = (C) Copyright EPCL 1987 = */ 454 /* ================================================================ */ 455 456 *&*&nclude subsys:cinserts_stddef*/ 457 /* ================================================================ */ 458 /* = EMAS C Header file = */ 459 /* = = */ 460 /* = stddef.h = */ 461 /* = = */ 462 /* = (C) Copyright EPCL 1987 = */ 463 /* ================================================================ */ 464 465 typedef int ptrdiff_t; 466 typedef int size_t; 467 #define NULL 0 468 extern ICL9CAERRNO; 469 #define errno ICL9CAERRNO 470 &*&*nd of include file */ 471 472 #define _NFILE 255 473 #define NULL 0 474 typedef int FILE; 475 #define _IOFBF 2 476 #define _IOLBF 1 477 #define _IONBF 0 478 #define BUFSIZ 2036 479 #define EOF -1 480 #define L_tmpnam 27 481 #define SEEK_CUR 1 482 #define SEEK_END 2 483 #define SEEK_SET 0 484 #define SYS_OPEN 78 485 #define TMP_MAX 1000 486 #define stderr 2 487 #define stdin 0 488 #define stdout 1 489 490 491 int remove (); 492 int rename (); 493 FILE *tmpfile (); 494 char *tmpnam (); 495 496 int fclose (); 497 int fflush (); 498 499 FILE *fopen (); 500 FILE *freopen (); 501 502 int setvbuf (); 503 void setbuf (); 504 505 int fprintf (); 506 int printf (); 507 int sprintf (); 508 509 int fscanf (); 510 int scanf (); 511 int sscanf (); 512 513 int fgetc (); 514 int getc (); 515 int getchar (); 516 517 char *fgets (); 518 char *gets (); 519 520 int fputc (); 521 int putc (); 522 int putchar (); 523 524 int fputs (); 525 int puts (); 526 527 int ungetc (); 528 529 int fread (); 530 int fwrite (); 531 532 int fseek (); 533 long ftell (); 534 void rewind (); 535 536 void clearerr (); 537 int feof (); 538 int ferror (); 539 void perror (); 540 541 &*&*nd of include file */ 542 /* for strcpy, strcmp */ 543 544 #define Null 0 545 /* Value of a Null pointer */ 546 #define true 1 547 #define false 0 548 549 typedef int One_Thirty; 550 typedef int One_Fifty; 551 typedef char Capital_Letter; 552 typedef int Boolean; 553 typedef char Str_30 [31]; 554 typedef int Arr_1_Dim [50]; 555 typedef int Arr_2_Dim [50] [50]; 556 557 typedef struct record 558 { 559 struct record *Ptr_Comp; 560 Enumeration Discr; 561 union { 562 struct { 563 Enumeration Enum_Comp; 564 int Int_Comp; 565 char Str_Comp [31]; 566 } var_1; 567 struct { 568 Enumeration E_Comp_2; 569 char Str_2_Comp [31]; 570 } var_2; 571 struct { 572 char Ch_1_Comp; 573 char Ch_2_Comp; 574 } var_3; 575 } variant; 576 } Rec_Type, *Rec_Pointer; 577 578 579 &*&*nd of include file */ 580 581 /* Global Variables: */ 582 583 Rec_Pointer Ptr_Glob, 584 Next_Ptr_Glob; 585 int Int_Glob; 586 Boolean Bool_Glob; 587 char Ch_1_Glob, 588 Ch_2_Glob; 589 int Arr_1_Glob [50]; 590 int Arr_2_Glob [50] [50]; 591 592 extern char *malloc (); 593 Enumeration Func_1 (); 594 /* forward declaration necessary since Enumeration may not simply be int */ 595 596 #ifndef REG 597 Boolean Reg = false; 598 #define REG 599 /* REG becomes defined as empty */ 600 /* i.e. no register variables */ 601 #else 602 Boolean Reg = true; 603 #endif 604 605 /* variables for time measurement: */ 606 607 #ifdef TIMES 608 struct tms time_info; 609 extern int times (); 610 /* see library function "times" */ 611 #define Too_Small_Time (2*HZ) 612 /* Measurements should last at least about 2 seconds */ 613 #endif 614 #ifdef TIME 615 extern int dcputime(); 616 /* see library function "time" */ 617 #define Too_Small_Time 2 618 /* Measurements should last at least 2 seconds */ 619 #endif 620 #ifdef MSC_CLOCK 621 extern clock_t clock(); 622 #define Too_Small_Time (2*HZ) 623 #endif 624 625 int Begin_Time, 626 End_Time, 627 User_Time; 628 float Microseconds, 629 Dhrystones_Per_Second; 630 631 /* end of variables for time measurement */ 632 633 634 main () 635 /*****/ 636 637 /* main program, corresponds to procedures */ 638 /* Main and Proc_0 in the Ada version */ 639 { 640 One_Fifty Int_1_Loc; 641 REG One_Fifty Int_2_Loc; 642 One_Fifty Int_3_Loc; 643 REG char Ch_Index; 644 Enumeration Enum_Loc; 645 Str_30 Str_1_Loc; 646 Str_30 Str_2_Loc; 647 REG int Run_Index; 648 REG int Number_Of_Runs; 649 650 /* Initializations */ 651 652 Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); 653 Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); 654 655 Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; 656 Ptr_Glob->Discr = Ident_1; 657 Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; 658 Ptr_Glob->variant.var_1.Int_Comp = 40; 659 strcpy (Ptr_Glob->variant.var_1.Str_Comp, 660 "DHRYSTONE PROGRAM, SOME STRING"); 661 strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); 662 663 Arr_2_Glob [8][7] = 10; 664 /* Was missing in published program. Without this statement, */ 665 /* Arr_2_Glob [8][7] would have an undefined value. */ 666 /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ 667 /* overflow may occur for this array element. */ 668 669 printf ("\n"); 670 printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); 671 printf ("\n"); 672 if (Reg) 673 { 674 printf ("Program compiled with 'register' attribute\n"); 675 printf ("\n"); 676 } 677 else 678 { 679 printf ("Program compiled without 'register' attribute\n"); 680 printf ("\n"); 681 } 682 printf ("Please give the number of runs through the benchmark: "); 683 { 684 int n; 685 scanf ("%d", &n); 686 Number_Of_Runs = n; 687 } 688 printf ("\n"); 689 690 printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); 691 692 /***************/ 693 /* Start timer */ 694 /***************/ 695 696 #ifdef TIMES 697 times (&time_info); 698 Begin_Time = (long) time_info.tms_utime; 699 #endif 700 #ifdef TIME 701 Begin_Time = dcputime (); 702 #endif 703 #ifdef MSC_CLOCK 704 Begin_Time = clock(); 705 #endif 706 707 for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) 708 { 709 710 Proc_5(); 711 Proc_4(); 712 /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ 713 Int_1_Loc = 2; 714 Int_2_Loc = 3; 715 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); 716 Enum_Loc = Ident_2; 717 Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); 718 /* Bool_Glob == 1 */ 719 while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ 720 { 721 Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; 722 /* Int_3_Loc == 7 */ 723 Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); 724 /* Int_3_Loc == 7 */ 725 Int_1_Loc += 1; 726 } /* while */ 727 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ 728 Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); 729 /* Int_Glob == 5 */ 730 Proc_1 (Ptr_Glob); 731 for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) 732 /* loop body executed twice */ 733 { 734 if (Enum_Loc == Func_1 (Ch_Index, 'C')) 735 /* then, not executed */ 736 { 737 Proc_6 (Ident_1, &Enum_Loc); 738 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); 739 Int_2_Loc = Run_Index; 740 Int_Glob = Run_Index; 741 } 742 } 743 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ 744 Int_2_Loc = Int_2_Loc * Int_1_Loc; 745 Int_1_Loc = Int_2_Loc / Int_3_Loc; 746 Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; 747 /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ 748 Proc_2 (&Int_1_Loc); 749 /* Int_1_Loc == 5 */ 750 751 } /* loop "for Run_Index" */ 752 753 /**************/ 754 /* Stop timer */ 755 /**************/ 756 757 #ifdef TIMES 758 times (&time_info); 759 End_Time = (long) time_info.tms_utime; 760 #endif 761 #ifdef TIME 762 End_Time = dcputime (); 763 #endif 764 #ifdef MSC_CLOCK 765 End_Time = clock(); 766 #endif 767 768 printf ("Execution ends\n"); 769 printf ("\n"); 770 printf ("Final values of the variables used in the benchmark:\n"); 771 printf ("\n"); 772 printf ("Int_Glob: %d\n", Int_Glob); 773 printf (" should be: %d\n", 5); 774 printf ("Bool_Glob: %d\n", Bool_Glob); 775 printf (" should be: %d\n", 1); 776 printf ("Ch_1_Glob: %c\n", Ch_1_Glob); 777 printf (" should be: %c\n", 'A'); 778 printf ("Ch_2_Glob: %c\n", Ch_2_Glob); 779 printf (" should be: %c\n", 'B'); 780 printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); 781 printf (" should be: %d\n", 7); 782 printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); 783 printf (" should be: Number_Of_Runs + 10\n"); 784 printf ("Ptr_Glob->\n"); 785 printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); 786 printf (" should be: (implementation-dependent)\n"); 787 printf (" Discr: %d\n", Ptr_Glob->Discr); 788 printf (" should be: %d\n", 0); 789 printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); 790 printf (" should be: %d\n", 2); 791 printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); 792 printf (" should be: %d\n", 17); 793 printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); 794 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); 795 printf ("Next_Ptr_Glob->\n"); 796 printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); 797 printf (" should be: (implementation-dependent), same as above\n"); 798 printf (" Discr: %d\n", Next_Ptr_Glob->Discr); 799 printf (" should be: %d\n", 0); 800 printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); 801 printf (" should be: %d\n", 1); 802 printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); 803 printf (" should be: %d\n", 18); 804 printf (" Str_Comp: %s\n", 805 Next_Ptr_Glob->variant.var_1.Str_Comp); 806 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); 807 printf ("Int_1_Loc: %d\n", Int_1_Loc); 808 printf (" should be: %d\n", 5); 809 printf ("Int_2_Loc: %d\n", Int_2_Loc); 810 printf (" should be: %d\n", 13); 811 printf ("Int_3_Loc: %d\n", Int_3_Loc); 812 printf (" should be: %d\n", 7); 813 printf ("Enum_Loc: %d\n", Enum_Loc); 814 printf (" should be: %d\n", 1); 815 printf ("Str_1_Loc: %s\n", Str_1_Loc); 816 printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); 817 printf ("Str_2_Loc: %s\n", Str_2_Loc); 818 printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); 819 printf ("\n"); 820 821 User_Time = (End_Time - Begin_Time)/1000; 822 823 if (User_Time < Too_Small_Time) 824 { 825 printf ("Measured time too small to obtain meaningful results\n"); 826 printf ("Please increase number of runs\n"); 827 printf ("\n"); 828 } 829 else 830 { 831 #ifdef TIME 832 Microseconds = (float) User_Time * Mic_secs_Per_Second 833 / (float) Number_Of_Runs; 834 Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; 835 #else 836 Microseconds = (float) User_Time * Mic_secs_Per_Second 837 / ((float) HZ * ((float) Number_Of_Runs)); 838 Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs) 839 / (float) User_Time; 840 #endif 841 printf ("Microseconds for one run through Dhrystone: "); 842 printf ("%6.1f \n", Microseconds); 843 printf ("Dhrystones per Second: "); 844 printf ("%6.1f \n", Dhrystones_Per_Second); 845 printf ("\n"); 846 } 847 848 } 849 850 851 Proc_1 (Ptr_Val_Par) 852 /******************/ 853 854 REG Rec_Pointer Ptr_Val_Par; 855 /* executed once */ 856 { 857 REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; 858 /* == Ptr_Glob_Next */ 859 /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ 860 /* corresponds to "rename" in Ada, "with" in Pascal */ 861 862 structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 863 Ptr_Val_Par->variant.var_1.Int_Comp = 5; 864 Next_Record->variant.var_1.Int_Comp 865 = Ptr_Val_Par->variant.var_1.Int_Comp; 866 Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; 867 Proc_3 (&Next_Record->Ptr_Comp); 868 /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 869 == Ptr_Glob->Ptr_Comp */ 870 if (Next_Record->Discr == Ident_1) 871 /* then, executed */ 872 { 873 Next_Record->variant.var_1.Int_Comp = 6; 874 Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 875 &Next_Record->variant.var_1.Enum_Comp); 876 Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; 877 Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 878 &Next_Record->variant.var_1.Int_Comp); 879 } 880 else /* not executed */ 881 structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); 882 } /* Proc_1 */ 883 884 885 Proc_2 (Int_Par_Ref) 886 /******************/ 887 /* executed once */ 888 /* *Int_Par_Ref == 1, becomes 4 */ 889 890 One_Fifty *Int_Par_Ref; 891 { 892 One_Fifty Int_Loc; 893 Enumeration Enum_Loc; 894 895 Int_Loc = *Int_Par_Ref + 10; 896 do /* executed once */ 897 if (Ch_1_Glob == 'A') 898 /* then, executed */ 899 { 900 Int_Loc -= 1; 901 *Int_Par_Ref = Int_Loc - Int_Glob; 902 Enum_Loc = Ident_1; 903 } /* if */ 904 while (Enum_Loc != Ident_1); /* true */ 905 } /* Proc_2 */ 906 907 908 Proc_3 (Ptr_Ref_Par) 909 /******************/ 910 /* executed once */ 911 /* Ptr_Ref_Par becomes Ptr_Glob */ 912 913 Rec_Pointer *Ptr_Ref_Par; 914 915 { 916 if (Ptr_Glob != Null) 917 /* then, executed */ 918 *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; 919 Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); 920 } /* Proc_3 */ 921 922 923 Proc_4 () /* without parameters */ 924 /*******/ 925 /* executed once */ 926 { 927 Boolean Bool_Loc; 928 929 Bool_Loc = Ch_1_Glob == 'A'; 930 Bool_Glob = Bool_Loc | Bool_Glob; 931 Ch_2_Glob = 'B'; 932 } /* Proc_4 */ 933 934 935 Proc_5 () /* without parameters */ 936 /*******/ 937 /* executed once */ 938 { 939 Ch_1_Glob = 'A'; 940 Bool_Glob = false; 941 } /* Proc_5 */ 942 943 944 /* Procedure for the assignment of structures, */ 945 /* if the C compiler doesn't support this feature */ 946 #ifdef NOSTRUCTASSIGN 947 memcpy (d, s, l) 948 register char *d; 949 register char *s; 950 register int l; 951 { 952 while (l--) *d++ = *s++; 953 } 954 #endif 955 956 PREPROCESSOR LISTING 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} 19 Enumeration; 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 typedef int ptrdiff_t; 43 typedef int size_t; 44 extern ICL9CAERRNO; 45 46 47 typedef int FILE; 48 int remove (); 49 int rename (); 50 FILE *tmpfile (); 51 char *tmpnam (); 52 53 int fclose (); 54 int fflush (); 55 56 FILE *fopen (); 57 FILE *freopen (); 58 59 int setvbuf (); 60 void setbuf (); 61 62 int fprintf (); 63 int printf (); 64 int sprintf (); 65 66 int fscanf (); 67 int scanf (); 68 int sscanf (); 69 70 int fgetc (); 71 int getc (); 72 int getchar (); 73 74 char *fgets (); 75 char *gets (); 76 77 int fputc (); 78 int putc (); 79 int putchar (); 80 81 int fputs (); 82 int puts (); 83 84 int ungetc (); 85 86 int fread (); 87 int fwrite (); 88 89 int fseek (); 90 long ftell (); 91 void rewind (); 92 93 void clearerr (); 94 int feof (); 95 int ferror (); 96 void perror (); 97 98 99 100 101 102 typedef int One_Thirty; 103 typedef int One_Fifty; 104 typedef char Capital_Letter; 105 typedef int Boolean; 106 typedef char Str_30 [31]; 107 typedef int Arr_1_Dim [50]; 108 typedef int Arr_2_Dim [50] [50]; 109 110 typedef struct record 111 { 112 struct record *Ptr_Comp; 113 Enumeration Discr; 114 union { 115 struct { 116 Enumeration Enum_Comp; 117 int Int_Comp; 118 char Str_Comp [31]; 119 } var_1; 120 struct { 121 Enumeration E_Comp_2; 122 char Str_2_Comp [31]; 123 } var_2; 124 struct { 125 char Ch_1_Comp; 126 char Ch_2_Comp; 127 } var_3; 128 } variant; 129 } Rec_Type, *Rec_Pointer; 130 131 132 133 134 135 136 Rec_Pointer Ptr_Glob, 137 Next_Ptr_Glob; 138 int Int_Glob; 139 Boolean Bool_Glob; 140 char Ch_1_Glob, 141 Ch_2_Glob; 142 int Arr_1_Glob [50]; 143 int Arr_2_Glob [50] [50]; 144 145 extern char *malloc (); 146 Enumeration Func_1 (); 147 148 149 Boolean Reg = 0; 150 151 152 153 extern int dcputime(); 154 int Begin_Time, 155 End_Time, 156 User_Time; 157 float Microseconds, 158 Dhrystones_Per_Second; 159 160 161 162 163 main () 164 165 166 167 168 { 169 One_Fifty Int_1_Loc; 170 One_Fifty Int_2_Loc; 171 One_Fifty Int_3_Loc; 172 char Ch_Index; 173 Enumeration Enum_Loc; 174 Str_30 Str_1_Loc; 175 Str_30 Str_2_Loc; 176 int Run_Index; 177 int Number_Of_Runs; 178 179 180 Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); 181 Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); 182 183 Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; 184 Ptr_Glob->Discr = Ident_1; 185 Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; 186 Ptr_Glob->variant.var_1.Int_Comp = 40; 187 strcpy (Ptr_Glob->variant.var_1.Str_Comp, 188 "DHRYSTONE PROGRAM, SOME STRING"); 189 strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); 190 191 Arr_2_Glob [8][7] = 10; 192 193 194 195 196 197 printf ("\n"); 198 printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); 199 printf ("\n"); 200 if (Reg) 201 { 202 printf ("Program compiled with 'register' attribute\n"); 203 printf ("\n"); 204 } 205 else 206 { 207 printf ("Program compiled without 'register' attribute\n"); 208 printf ("\n"); 209 } 210 printf ("Please give the number of runs through the benchmark: "); 211 { 212 int n; 213 scanf ("%d", &n); 214 Number_Of_Runs = n; 215 } 216 printf ("\n"); 217 218 printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); 219 220 221 222 223 224 Begin_Time = dcputime (); 225 for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) 226 { 227 228 Proc_5(); 229 Proc_4(); 230 231 Int_1_Loc = 2; 232 Int_2_Loc = 3; 233 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); 234 Enum_Loc = Ident_2; 235 Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); 236 237 while (Int_1_Loc < Int_2_Loc) 238 { 239 Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; 240 241 Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); 242 243 Int_1_Loc += 1; 244 } 245 246 Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); 247 248 Proc_1 (Ptr_Glob); 249 for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) 250 251 { 252 if (Enum_Loc == Func_1 (Ch_Index, 'C')) 253 254 { 255 Proc_6 (Ident_1, &Enum_Loc); 256 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); 257 Int_2_Loc = Run_Index; 258 Int_Glob = Run_Index; 259 } 260 } 261 262 Int_2_Loc = Int_2_Loc * Int_1_Loc; 263 Int_1_Loc = Int_2_Loc / Int_3_Loc; 264 Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; 265 266 Proc_2 (&Int_1_Loc); 267 268 269 } 270 271 272 273 274 275 End_Time = dcputime (); 276 printf ("Execution ends\n"); 277 printf ("\n"); 278 printf ("Final values of the variables used in the benchmark:\n"); 279 printf ("\n"); 280 printf ("Int_Glob: %d\n", Int_Glob); 281 printf (" should be: %d\n", 5); 282 printf ("Bool_Glob: %d\n", Bool_Glob); 283 printf (" should be: %d\n", 1); 284 printf ("Ch_1_Glob: %c\n", Ch_1_Glob); 285 printf (" should be: %c\n", 'A'); 286 printf ("Ch_2_Glob: %c\n", Ch_2_Glob); 287 printf (" should be: %c\n", 'B'); 288 printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); 289 printf (" should be: %d\n", 7); 290 printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); 291 printf (" should be: Number_Of_Runs + 10\n"); 292 printf ("Ptr_Glob->\n"); 293 printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); 294 printf (" should be: (implementation-dependent)\n"); 295 printf (" Discr: %d\n", Ptr_Glob->Discr); 296 printf (" should be: %d\n", 0); 297 printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); 298 printf (" should be: %d\n", 2); 299 printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); 300 printf (" should be: %d\n", 17); 301 printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); 302 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); 303 printf ("Next_Ptr_Glob->\n"); 304 printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); 305 printf (" should be: (implementation-dependent), same as above\n"); 306 printf (" Discr: %d\n", Next_Ptr_Glob->Discr); 307 printf (" should be: %d\n", 0); 308 printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); 309 printf (" should be: %d\n", 1); 310 printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); 311 printf (" should be: %d\n", 18); 312 printf (" Str_Comp: %s\n", 313 Next_Ptr_Glob->variant.var_1.Str_Comp); 314 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); 315 printf ("Int_1_Loc: %d\n", Int_1_Loc); 316 printf (" should be: %d\n", 5); 317 printf ("Int_2_Loc: %d\n", Int_2_Loc); 318 printf (" should be: %d\n", 13); 319 printf ("Int_3_Loc: %d\n", Int_3_Loc); 320 printf (" should be: %d\n", 7); 321 printf ("Enum_Loc: %d\n", Enum_Loc); 322 printf (" should be: %d\n", 1); 323 printf ("Str_1_Loc: %s\n", Str_1_Loc); 324 printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); 325 printf ("Str_2_Loc: %s\n", Str_2_Loc); 326 printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); 327 printf ("\n"); 328 329 User_Time = (End_Time - Begin_Time)/1000; 330 331 if (User_Time < 2) 332 { 333 printf ("Measured time too small to obtain meaningful results\n"); 334 printf ("Please increase number of runs\n"); 335 printf ("\n"); 336 } 337 else 338 { 339 Microseconds = (float) User_Time * 1000000.0 340 / (float) Number_Of_Runs; 341 Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; 342 printf ("Microseconds for one run through Dhrystone: "); 343 printf ("%6.1f \n", Microseconds); 344 printf ("Dhrystones per Second: "); 345 printf ("%6.1f \n", Dhrystones_Per_Second); 346 printf ("\n"); 347 } 348 349 } 350 351 352 Proc_1 (Ptr_Val_Par) 353 354 355 Rec_Pointer Ptr_Val_Par; 356 357 { 358 Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; 359 360 361 362 363 *Ptr_Val_Par->Ptr_Comp = *Ptr_Glob; 364 Ptr_Val_Par->variant.var_1.Int_Comp = 5; 365 Next_Record->variant.var_1.Int_Comp 366 = Ptr_Val_Par->variant.var_1.Int_Comp; 367 Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; 368 Proc_3 (&Next_Record->Ptr_Comp); 369 370 if (Next_Record->Discr == Ident_1) 371 372 { 373 Next_Record->variant.var_1.Int_Comp = 6; 374 Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 375 &Next_Record->variant.var_1.Enum_Comp); 376 Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; 377 Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 378 &Next_Record->variant.var_1.Int_Comp); 379 } 380 else 381 *Ptr_Val_Par = *Ptr_Val_Par->Ptr_Comp; 382 } 383 384 385 Proc_2 (Int_Par_Ref) 386 387 388 389 390 One_Fifty *Int_Par_Ref; 391 { 392 One_Fifty Int_Loc; 393 Enumeration Enum_Loc; 394 395 Int_Loc = *Int_Par_Ref + 10; 396 do 397 if (Ch_1_Glob == 'A') 398 399 { 400 Int_Loc -= 1; 401 *Int_Par_Ref = Int_Loc - Int_Glob; 402 Enum_Loc = Ident_1; 403 } 404 while (Enum_Loc != Ident_1); 405 } 406 407 408 Proc_3 (Ptr_Ref_Par) 409 410 411 412 413 Rec_Pointer *Ptr_Ref_Par; 414 415 { 416 if (Ptr_Glob != 0 ) 417 418 *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; 419 Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); 420 } 421 422 423 Proc_4 () 424 425 426 { 427 Boolean Bool_Loc; 428 429 Bool_Loc = Ch_1_Glob == 'A'; 430 Bool_Glob = Bool_Loc | Bool_Glob; 431 Ch_2_Glob = 'B'; 432 } 433 434 435 Proc_5 () 436 437 438 { 439 Ch_1_Glob = 'A'; 440 Bool_Glob = 0; 441 } 442 443 444 445 446