home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / bench / Dhrystone / source / DhrystoneSRC.lha / dhry / dhry.p < prev    next >
Text File  |  1990-03-18  |  37KB  |  840 lines

  1. (*
  2.  ****************************************************************************
  3.  *
  4.  *                   "DHRYSTONE" Benchmark Program
  5.  *                   -----------------------------
  6.  *                                                                            
  7.  *  Version:    Pascal, Version 2.1
  8.  *                                                                            
  9.  *  File:       dhry.p
  10.  *
  11.  *  Date:       May 25, 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.  *              This version uses calls to the Pascal runtime library of the
  28.  *              Berkeley UNIX system (4.3 bsd) for time measurement.
  29.  *              For measurements on other systems, these calls need to be
  30.  *              modified.                                
  31.  *                                                                           
  32.  *  Collection of Results:
  33.  *              Reinhold Weicker (address see above) and
  34.  *              
  35.  *              Rick Richardson
  36.  *              PC Research. Inc.
  37.  *              94 Apple Orchard Drive
  38.  *              Tinton Falls, NJ 07724
  39.  *                      Phone:  (201) 834-1378 (9-17 EST)               
  40.  *                      Usenet: ...!seismo!uunet!pcrat!rick
  41.  *
  42.  *      Please send results to Rick Richardson and/or Reinhold Weicker.
  43.  *      Complete information should be given on hardware and software used.
  44.  *      Hardware information includes: Machine type, CPU, type and size
  45.  *      of caches; for microprocessors: clock frequency, memory speed
  46.  *      (number of wait states).
  47.  *      Software information includes: Compiler (and runtime library)
  48.  *      manufacturer and version, compilation switches, OS version.
  49.  *      The Operating System version may give an indication about the
  50.  *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
  51.  *
  52.  *      The complete output generated by the program should be mailed
  53.  *      such that at least some checks for correctness can be made.
  54.  *
  55.  ****************************************************************************
  56.  *
  57.  *  History:    This version Pascal/2.1 has been made for two reasons:
  58.  *
  59.  *              1) There is a need for a common Pascal version of
  60.  *              Dhrystone. Although translation from the published (Ada)
  61.  *              version to Pascal is straightforward in most aspects,
  62.  *              there are cases where it may not be obvious to everyone.
  63.  *              There should be, as far as possible, only one Pascal version
  64.  *              of Dhrystone such that results can be compared without
  65.  *              restrictions. Also, a Pascal version of Dhrystone has not yet
  66.  *              found a network distribution comparable to the C version
  67.  *              (version 1.1) distributed by Rick Richardson.
  68.  *              
  69.  *              2) As far as it is possible without changes to the Dhrystone
  70.  *              statistics, optimizing compilers should be prevented from
  71.  *              removing significant statements.
  72.  *
  73.  *              This Pascal version 2.1 has been made consistent with the
  74.  *              C version 2.1; therefore the acknowledgments for the C version
  75.  *              are due for the Pascal version as well: I thank
  76.  *              Rick Richardson (Tinton Falls, NJ), Chaim Benedelac (Nat.
  77.  *              Semi.), David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
  78.  *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
  79.  *              for their help with comments on earlier versions of the
  80.  *              benchmark.
  81.  *
  82.  *  Changes:    In the initialization part, this version differs 
  83.  *              from the Pascal version previously distributed by Reinhold
  84.  *              Weicker, the number of runs through Dhrystone is obtained
  85.  *              interactively from the terminal. Output of the result 
  86.  *              has been changed to conform to the C version (2.1).
  87.  *              The changes in the initialization part and in the printing
  88.  *              of the result have no impact on performance measurement 
  89.  *              since they are outside the measaurement loop.
  90.  *              
  91.  *              Inside the measurement loop, this version follows the
  92.  *              version previously distributed by Reinhold Weicker.
  93.  *              As a correction to the published version, a statement
  94.  *              initializing Array2Glob [8,7] (outside the measurement
  95.  *              loop) has been added. Otherwise, this array element would
  96.  *              have an undefined value.
  97.  *
  98.  *              At several places in the benchmark, code has been added,
  99.  *              but within the measurement loop only in branches that 
  100.  *              are not executed. The intention is that optimizing compilers
  101.  *              should be prevented from moving code out of the measurement
  102.  *              loop, or from removing code altogether. Since the statements
  103.  *              that are executed within the measurement loop have NOT been
  104.  *              changed, all numbers defining the "Dhrystone distribution"
  105.  *              (distribution of statements, operand types and locality)
  106.  *              still hold. Except for sophisticated optimizing compilers,
  107.  *              execution times for this version should be the same as
  108.  *              for previous versions.
  109.  *
  110.  *              Since it has proven difficult to subtract the time for the
  111.  *              measurement loop overhead in a correct way, the loop check
  112.  *              has been made a part of the benchmark. This does have
  113.  *              an impact - though a very minor one - on the distribution
  114.  *              statistics which have been updated for this version.
  115.  *
  116.  *              All changes within the measurement loop are described
  117.  *              and discussed in the companion paper "Rationale for
  118.  *              Dhrystone version 2".
  119.  *
  120.  *              Because of the self-imposed limitation that the order and
  121.  *              distribution of the executed statements should not be
  122.  *              changed, there are still cases where optimizing compilers
  123.  *              may not generate code for some statements. To a certain
  124.  *              degree, this is unavoidable for small synthetic benchmarks.
  125.  *              Users of the benchmark are advised to check code listings
  126.  *              whether code is generated for all statements of Dhrystone.
  127.  *
  128.  *              Version 2.1 is identical to version 2.0 distributed via
  129.  *              the UNIX network Usenet in March 1988 except that it corrects
  130.  *              some minor deficiencies that were found by users of version 2.0.
  131.  *              The only change within the measurement loop is that a
  132.  *              non-executed "else" part was added to the "if" statement in
  133.  *              Func3, and a non-executed "else" part removed from Proc3.
  134.  *
  135.  ***************************************************************************
  136.  *
  137.  *  Compilation model and measurement (IMPORTANT):
  138.  *
  139.  *  This program contains the Dhrystone program, including measurement setup,
  140.  *  in one file. The original (Ada) program contained three packages,
  141.  *  - a package with global type definitions,
  142.  *  - Pack_1, containing the main program (Proc_0 in Ada) and procedures
  143.  *            Proc_1, ... , Proc_5,
  144.  *  - Pack_2, containing Proc_6, ... , Proc_8, Func_1, ..., Func_3.
  145.  *  Since ISO/ANSI Standard Pascal provides no means to express separate
  146.  *  compilation (although many Pascal implementations provide such a feature),
  147.  *  it is not possible to formulate a portable Pascal version with the program
  148.  *  in several modules, corresponding more closely to the Ada and C versions.
  149.  *  Therefore, no attempt has been made to construct a Pascal version with
  150.  *  the program consisting of several modules.
  151.  *                                                                           
  152.  *  This difference may impact execution time because the compiler can
  153.  *  perform more data flow analysis for a single-module program;
  154.  *  sophisticated compilers may be able to suppress code generation for
  155.  *  some parts of the program.
  156.  *  Users should check machine code listings generated by the compiler
  157.  *  to ensure that code is generated for all parts of the program.
  158.  *
  159.  *  The following "ground rules" apply for measurements:
  160.  *  - No procedure merging
  161.  *  - Otherwise, compiler optimizations are allowed but should be indicated
  162.  *  See the companion paper "Rationale for Dhrystone Version 2" for a more
  163.  *  detailed discussion of these ground rules.
  164.  *
  165.  *  For 16-Bit processors (e.g. 80x86), times for all compilation models
  166.  *  ("small", "medium", "large") should be given if possible, together
  167.  *  with a definition of these models for the compiler system used.
  168.  *
  169.  **************************************************************************
  170.  *
  171.  *  Dhrystone (Pascal version) statistics:
  172.  *
  173.  *  [Comment from the first distribution by Reinhold Weicker,
  174.  *   the distribution statistics have been updated for Version 2.1.
  175.  *   Note that because of language differences, the numbers are different
  176.  *   from the Ada version. The main difference is that the variables that
  177.  *   are local variables of "Proc_0" (Ada) or "main" (C) are global
  178.  *   variables in the Pascal version.]
  179.  *                                                                           
  180.  *  The following program contains statements of a high level programming    
  181.  *  language (here: Pascal) in a distribution considered representative:     
  182.  *                                                                           
  183.  *    assignments                  58
  184.  *    control statements           28
  185.  *    procedure, function calls    15
  186.  *                                                                           
  187.  *  100 statements are dynamically executed. The program is balanced with    
  188.  *  respect to the three aspects:                                            
  189.  *                                                                           
  190.  *    - statement type                                                       
  191.  *    - operand type (for simple data types)                                 
  192.  *    - operand access                                                       
  193.  *         operand global, local, parameter, or constant.                    
  194.  *           There is no static nesting of blocks or procedures,             
  195.  *           therefore all variables are either global or local.             
  196.  *                                                                           
  197.  *  The combination of these three aspects is balanced only approximately.   
  198.  *                                                                           
  199.  *  1. Statement Type:                                                       
  200.  *  -----------------             number
  201.  *                                                                           
  202.  *     V1 := V2                   15                                         
  203.  *     V := Constant              12                                         
  204.  *       (incl. V1 := F(..)                                                  
  205.  *     Assignment,                 7                                         
  206.  *       with array element                                                  
  207.  *     Assignment,                 6                                         
  208.  *       with record component                                               
  209.  *                                --                                       
  210.  *                                40       40                                
  211.  *                                                                           
  212.  *     X := Y +|-|and|or Z         5                                         
  213.  *     X := Y +|-|"=" Constant     6                                         
  214.  *     X := X +|- 1                3                                         
  215.  *     X := Y *|/ Z                2                                         
  216.  *     X := Expression,            1                                         
  217.  *          two operators                                                    
  218.  *     X := Expression,            1                                         
  219.  *          three operators                                                  
  220.  *                                --                                         
  221.  *                                18       18                                
  222.  *                                                                           
  223.  *     if .... then ....          14                                         
  224.  *       with "else"      7                                                  
  225.  *       without "else"   7                                                  
  226.  *           executed        3                                               
  227.  *           not executed    4                                               
  228.  *     for I in 1..N do ...        7  |  counted every time                  
  229.  *     while ... do ...            4  |  the loop condition                  
  230.  *     repeat ... until            1  |  is evaluated                        
  231.  *     case ... end                1                                         
  232.  *     with                        1                                         
  233.  *                                --                                         
  234.  *                                28       28                                
  235.  *                                                                           
  236.  *     P (...)  procedure call    10                                         
  237.  *     X := F (...)                                                          
  238.  *             function  call      5                                         
  239.  *                                --                                         
  240.  *                                15       15                                
  241.  *                                        ---                              
  242.  *                                        101                                
  243.  *                                                                           
  244.  *    22 of the 58 assignments have a variable of a constrained              
  245.  *    (sub-)type as their destination. In general, discriminant checks       
  246.  *    will be necessary in these cases; however, the compiler may            
  247.  *    optimize out some of these checks.                                     
  248.  *                                                                           
  249.  *    The average number of parameters in procedure or function calls        
  250.  *    is 1.80 (not counting the function values as implicit parameters).     
  251.  *                                                                           
  252.  *                                                                           
  253.  *  2. Operators                                                             
  254.  *  ------------                                                             
  255.  *                          number    approximate                            
  256.  *                                    percentage                             
  257.  *                                                                           
  258.  *    Arithmetic             27          52.9                                
  259.  *                                                                           
  260.  *       +                     16          31.4                              
  261.  *       -                      7          13.7                              
  262.  *       *                      3           5.9                              
  263.  *       div                    1           2.0                              
  264.  *                                                                           
  265.  *    Comparison             20           39.2                               
  266.  *                                                                           
  267.  *       =                      9           17.6                             
  268.  *       <>                     4            7.8                             
  269.  *       >                      1            2.0                             
  270.  *       <                      3            5.9                             
  271.  *       >=                     1            2.0                             
  272.  *       <=                     2            3.9                             
  273.  *                                                                           
  274.  *    Logic                   4            7.8                               
  275.  *                                                                           
  276.  *       AND                    1            2.0                             
  277.  *       OR                     1            2.0                             
  278.  *       NOT                    2            3.9                             
  279.  *                                                                           
  280.  *                           --          -----                               
  281.  *                           51           99.9                               
  282.  *                                                                           
  283.  *                                                                           
  284.  *  3. Operand Type (counted once per operand reference):                    
  285.  *  ---------------                                                          
  286.  *                          number    approximate                            
  287.  *                                    percentage                             
  288.  *                                                                           
  289.  *     Integer               135        54.7 %                               
  290.  *     Character              47        19.0 %                               
  291.  *     Enumeration            31        12.6 %                               
  292.  *     Boolean                13         5.3 %                               
  293.  *     Pointer                11         4.5 %                               
  294.  *     String30                6         2.4 %                               
  295.  *     Array                   2         0.8 %                               
  296.  *     Record                  2         0.8 %                               
  297.  *                           ---       -------                               
  298.  *                           247        100.1 %
  299.  *                                                                           
  300.  *  When there is an access path leading to the final operand (e.g. a record 
  301.  *  component), only the final data type on the access path is counted.      
  302.  *                                                                           
  303.  *  There are 16 accesses to components of a record, 9 of them go to         
  304.  *  a component in a variant part. For some of these accesses, the           
  305.  *  compiler may suppress generation of code checking the tag field          
  306.  *  during optimization.                                                     
  307.  *                                                                           
  308.  *                                                                           
  309.  *  3. Operand Locality:                                                     
  310.  *  -------------------                                                      
  311.  *                                                                           
  312.  *     local variable               84        34.0 %                         
  313.  *     global variable              58        23.5 %                         
  314.  *     parameter                    45        18.2 %                         
  315.  *        value                        23         9.3 %                      
  316.  *        reference                    22         8.9 %                      
  317.  *     function result               5         2.0 %                         
  318.  *     constant                     55        22.3 %                         
  319.  *                                 ---       -------                         
  320.  *                                 247       100.0 %                         
  321.  *                                                                           
  322.  *                                                                           
  323.  *  The program does not compute anything meaningful, but it is syntactically
  324.  *  and semantically correct. All variables have a value assigned to them    
  325.  *  before they are used as a source operand.                                
  326.  *                                                                           
  327.  *  There may be cases where a highly optimizing compiler may recognize      
  328.  *  unnecessary statements and may not generate code for them.               
  329.  *                                                                           
  330.  *  There has been no explicit effort to account for the effects of a        
  331.  *  cache, or to balance the use of long or short displacements for code or  
  332.  *  data.                                                                    
  333.  *                                                                           
  334.  ****************************************************************************
  335.  *)
  336.  
  337. program Dhrystone (input, output);
  338. (***************)
  339.  
  340. const (* for measurement *)
  341.  
  342.   MicrosecondsPerClock  = 1000;
  343.   ClocksPerSecond       = 1000;
  344.         (* In Berkeley UNIX Pascal, the function "clock"        *)
  345.         (* returns milliseconds                                 *)
  346.   TooSmallTime          = 2000;
  347.         (* Measurements should last at least 2 seconds          *)
  348.  
  349. type
  350.  
  351.   (* Global type definitions *)
  352.  
  353.   Enumeration           = (Ident1, Ident2, Ident3, Ident4, Ident5);
  354.  
  355.   OneToThirty           = 1..30;
  356.   OneToFifty            = 1..50;
  357.   CapitalLetter         = 'A'..'Z';
  358.  
  359.   String30              = packed array [OneToThirty] of char;
  360.  
  361.   Array1DimInteger      = array [OneToFifty] of integer;
  362.   Array2DimInteger      = array [OneToFifty, OneToFifty] of integer;
  363.  
  364.   RecordPointer         = ^RecordType;
  365.  
  366.   RecordType            =
  367.       record
  368.         PointerComp:   RecordPointer;
  369.         case Discr:    Enumeration of
  370.           Ident1:         (* only this variant is used,           *)
  371.                           (* but in some cases discriminant       *)
  372.                           (* checks are necessary                 *)
  373.             (EnumComp:      Enumeration;
  374.              IntComp:       OneToFifty;
  375.              StringComp:    String30);
  376.           Ident2:
  377.             (Enum2Comp:    Enumeration;
  378.              String2Comp:  String30);
  379.           Ident3, Ident4, Ident5:
  380.             (Char1Comp,
  381.              Char2Comp:    char);
  382.       end; (* record *)
  383.  
  384. var
  385.  
  386.   (* Ada version: Variables local in Proc_0 *)
  387.  
  388.   Int1Glob,
  389.   Int2Glob,
  390.   Int3Glob:       OneToFifty;
  391.   CharIndex:      char;
  392.   EnumGlob:       Enumeration;
  393.   String1Glob,
  394.   String2Glob:    String30;
  395.  
  396.   (* Ada version: Variables global in Pack_1 *)
  397.  
  398.   PointerGlob,
  399.   NextPointerGlob: RecordPointer;
  400.   IntGlob:         integer;
  401.  
  402.   BoolGlob:        boolean;
  403.   Char1Glob,
  404.   Char2Glob:       char;
  405.   Array1Glob:      Array1DimInteger;
  406.   Array2Glob:      Array2DimInteger;
  407.  
  408.   (* Variables for measurement *)
  409.  
  410.   RunIndex,
  411.   NumberOfRuns,
  412.   BeginClock,
  413.   EndClock,
  414.   SumClocks:            integer;
  415.   Microseconds,         
  416.   DhrystonesPerSecond:  real;
  417.   I:                    integer;
  418.  
  419.   (* end of variables for measurement *)
  420.  
  421. procedure Proc1 (    PointerParVal: RecordPointer);     forward;
  422.  
  423. procedure Proc2 (var IntParRef:     OneToFifty);        forward;
  424.  
  425. procedure Proc3 (var PointerParRef: RecordPointer);     forward;
  426.  
  427. procedure Proc4;                                        forward;
  428.   (* without parameters *)
  429.  
  430. procedure Proc5;                                        forward;
  431.   (* without parameters *)
  432.  
  433. procedure Proc6 (    EnumParVal:    Enumeration;
  434.                  var EnumParRef:    Enumeration);       forward;
  435.  
  436. procedure Proc7 (    Int1ParVal,
  437.                      Int2ParVal:    OneToFifty;
  438.                  var IntParRef:     OneToFifty);        forward;
  439.  
  440. procedure Proc8 (var Array1ParRef:  Array1DimInteger;
  441.                  var Array2ParRef:  Array2DimInteger;
  442.                      Int1ParVal,
  443.                      Int2ParVal:    integer);            forward;
  444.  
  445. function Func1  (    Char1ParVal,
  446.                      Char2ParVal:   CapitalLetter): 
  447.                                             Enumeration; forward;
  448.  
  449. function Func2  (var String1ParRef,
  450.                      String2ParRef: String30): 
  451.                                             boolean;      forward;
  452.  
  453. function Func3  (    EnumParVal:    Enumeration): 
  454.                                             boolean;      forward;
  455.  
  456.  
  457. procedure Proc1; (* (PointerParVal: RecordPointer) *)
  458.     (* executed once *)
  459. begin
  460.   with PointerParVal^.PointerComp^ (* = PointerGlobNext *) do
  461.   begin
  462.     PointerParVal^.PointerComp^ := PointerGlob^;
  463.     PointerParVal^.IntComp := 5;
  464.     IntComp := PointerParVal^.IntComp;
  465.     PointerComp := PointerParVal^.PointerComp;
  466.     Proc3 (PointerComp);
  467.       (* PointerParVal^.PointerComp^.PointerComp = PointerGlob^.PointerComp *)
  468.     if Discr = Ident1
  469.     then (* executed *)
  470.     begin
  471.       IntComp := 6;
  472.       Proc6 (PointerParVal^.EnumComp, EnumComp);
  473.       PointerComp := PointerGlob^.PointerComp;
  474.       Proc7 (IntComp, 10, IntComp);
  475.     end (* then *)
  476.     else (* not executed *)
  477.       PointerParVal^ := PointerParVal^.PointerComp^;
  478.   end; (* with *)
  479. end; (* Proc1 *)
  480.  
  481.  
  482. procedure Proc2; (* (var IntParRef: OneToFifty) *)
  483.     (* executed once *)
  484.     (* InParRef = 3, becomes 7 *)
  485. var
  486.   IntLoc:  OneToFifty;
  487.   EnumLoc: Enumeration;
  488. begin
  489.   IntLoc := IntParRef + 10;
  490.   repeat (* executed once *)
  491.     if Char1Glob = 'A'
  492.     then (* executed *)
  493.     begin
  494.       IntLoc := IntLoc - 1;
  495.       IntParRef := IntLoc - IntGlob;
  496.       EnumLoc := Ident1;
  497.     end (* if *)
  498.   until EnumLoc = Ident1; (* true *)
  499. end; (* Proc2 *)
  500.  
  501.  
  502. procedure Proc3; (* (var PointerParRef: RecordPointer) *)
  503.     (* executed once *)
  504.     (* PointerParRef becomes PointerGlob *)
  505. begin
  506.   if PointerGlob <> nil
  507.   then (* executed *)
  508.     PointerParRef := PointerGlob^.PointerComp;
  509.   Proc7 (10, IntGlob, PointerGlob^.IntComp);
  510. end; (* Proc3 *)
  511.  
  512.  
  513. procedure Proc4; (* without parameters *)
  514.     (* executed once *)
  515. var
  516.   BoolLoc: boolean;
  517. begin
  518.   BoolLoc := Char1Glob = 'A';
  519.   BoolGlob := BoolLoc or BoolGlob;
  520.   Char2Glob := 'B';
  521. end; (* Proc4 *)
  522.  
  523.  
  524. procedure Proc5; (* without parameters *)
  525.     (* executed once *)
  526. begin
  527.   Char1Glob := 'A';
  528.   BoolGlob := false;
  529. end; (* Proc5 *)
  530.  
  531.  
  532. procedure Proc6; (* (    EnumParVal:     Enumeration;
  533.                      var EnumParRef:     Enumeration) *)
  534.     (* executed once *)
  535.     (* EnumParVal = Ident3, EnumParRef becomes Ident2 *)
  536. begin
  537.   EnumParRef := EnumParVal;
  538.   if not Func3 (EnumParVal)
  539.   then (* not executed *)
  540.     EnumParRef := Ident4;
  541.   case EnumParVal of
  542.     Ident1: EnumParRef := Ident1;
  543.     Ident2: if IntGlob > 100
  544.               then EnumParRef := Ident1
  545.               else EnumParRef := Ident4;
  546.     Ident3: EnumParRef := Ident2;    (* executed *)
  547.     Ident4: ;
  548.     Ident5: EnumParRef := Ident3;
  549.   end; (* case *)
  550. end; (* Proc6 *)
  551.  
  552.  
  553. procedure Proc7; (* (    Int1ParVal,
  554.                          Int2ParVal:    OneToFifty;
  555.                      var IntParRef:     OneToFifty) *)
  556.     (* executed three times                               *)
  557.     (* first call:      Int1ParVal = 2, Int2ParVal = 3,   *)
  558.     (*                  IntParRef becomes 7               *)
  559.     (* second call:     Int1ParVal = 10, Int2ParVal = 5,  *)
  560.     (*                  IntParRef becomes 17              *)
  561.     (* third call:      Int1ParVal = 6, Int2ParVal = 10,  *)
  562.     (*                  IntParRef becomes 18              *)
  563. var
  564.   IntLoc: OneToFifty;
  565. begin
  566.   IntLoc := Int1ParVal + 2;
  567.   IntParRef := Int2ParVal + IntLoc;
  568. end; (* Proc7 *)
  569.  
  570.  
  571. procedure Proc8; (* (var Array1ParRef: Array1DimInteger;
  572.                      var Array2ParRef: Array2DimInteger;
  573.                          Int1ParVal,
  574.                          Int2ParVal:    integer)          *)
  575.     (* executed once  *)
  576.     (* Int1ParVal = 3 *)
  577.     (* Int2ParVal = 7 *)
  578. var
  579.   IntIndex,
  580.   IntLoc:   OneToFifty;
  581. begin
  582.   IntLoc := Int1ParVal + 5;
  583.   Array1ParRef [IntLoc] := Int2ParVal;
  584.   Array1ParRef [IntLoc+1] := Array1ParRef [IntLoc];
  585.   Array1ParRef [IntLoc+30] := IntLoc;
  586.   for IntIndex := IntLoc to IntLoc+1 do
  587.     Array2ParRef [IntLoc, IntIndex] := IntLoc;
  588.   Array2ParRef [IntLoc, IntLoc-1] := Array2ParRef [IntLoc, IntLoc-1] + 1;
  589.   Array2ParRef [IntLoc+20, IntLoc] := Array1ParRef [IntLoc];
  590.   IntGlob := 5;
  591. end; (* Proc8 *)
  592.  
  593.  
  594. function Func1; (* (Char1ParVal,
  595.                     Char2ParVal: CapitalLetter): Enumeration *)
  596.     (* executed three times, returns always Ident1              *)
  597.     (* first call:      Char1ParVal = 'H', Char2ParVal = 'R'    *)
  598.     (* second call:     Char1ParVal = 'A', Char2ParVal = 'C'    *)
  599.     (* third call:      Char1ParVal = 'B', Char2ParVal = 'C'    *)
  600. var
  601.   Char1Loc, Char2Loc: CapitalLetter;
  602. begin
  603.   Char1Loc := Char1ParVal;
  604.   Char2Loc := Char1Loc;
  605.   if Char2Loc <> Char2ParVal
  606.   then  (* executed *)
  607.     Func1 := Ident1
  608.   else  (* not executed *)
  609.   begin
  610.     Char1Glob := Char1Loc;
  611.     Func1 := Ident2;
  612.   end;
  613. end; (* Func1 *)
  614.  
  615.  
  616. function Func2; (* (var String1ParRef,
  617.                         String2ParRef: String30): boolean *)
  618.     (* executed once, returns false              *)
  619.     (* String1ParRef = 'DHRYSTONE PROGRAM, 1''ST STRING' *)
  620.     (* String2ParRef = 'DHRYSTONE PROGRAM, 2''ND STRING' *)
  621. var
  622.   IntLoc:  OneToThirty;
  623.   CharLoc: CapitalLetter;
  624. begin
  625.   IntLoc := 2;
  626.   while IntLoc <= 2 do (* loop body executed once *)
  627.     if Func1 (String1ParRef[IntLoc],
  628.               String2ParRef[IntLoc+1]) = Ident1
  629.     then (* executed *)
  630.     begin
  631.       CharLoc := 'A';
  632.       IntLoc := IntLoc + 1;
  633.     end; (* if, while *)
  634.   if (CharLoc >= 'W') and (CharLoc < 'Z')
  635.   then (* not executed *)
  636.     IntLoc := 7;
  637.   if CharLoc = 'R'
  638.   then (* not executed *)
  639.     Func2 := true
  640.   else (* executed *)
  641.   begin
  642.     if String1ParRef > String2ParRef
  643.     then (* not executed *)
  644.     begin
  645.       IntLoc := IntLoc + 7;
  646.       IntGlob := IntLoc;
  647.       Func2 := true
  648.     end
  649.     else (* executed *)
  650.       Func2 := false;
  651.   end; (* if CharLoc *)
  652. end; (* Func2 *)
  653.  
  654.  
  655. function Func3; (* (EnumParVal: Enumeration): boolean *)
  656.     (* executed once, returns true      *)
  657.     (* EnumParVal = Ident3              *)
  658. var
  659.   EnumLoc:  Enumeration;
  660. begin
  661.   EnumLoc := EnumParVal;
  662.   if EnumLoc = Ident3
  663.   then (* executed *)
  664.     Func3 := true
  665.   else (* not executed *)
  666.     Func3 := false;
  667. end; (* Func3 *)
  668.  
  669.  
  670. begin (* main program, corresponds to procedures        *)
  671.       (* Main and Proc_0 in the Ada version             *)
  672.  
  673.   (* Initializations *)
  674.  
  675.   new (NextPointerGlob);
  676.  
  677.   new (PointerGlob);
  678.  
  679.   PointerGlob^.PointerComp := NextPointerGlob;
  680.   PointerGlob^.Discr       := Ident1;
  681.   PointerGlob^.EnumComp    := Ident3;
  682.   PointerGlob^.IntComp     := 40;
  683.   PointerGlob^.StringComp  := 'DHRYSTONE PROGRAM, SOME STRING';
  684.  
  685.   String1Glob := 'DHRYSTONE PROGRAM, 1''ST STRING';
  686.  
  687.   Array2Glob [8,7] := 10;
  688.  
  689.   writeln;
  690.   writeln ('Dhrystone Benchmark, Version 2.1 (Language: Pascal)');
  691.   writeln;
  692.   writeln ('Please give the number of runs through the benchmark: ');
  693.   readln (NumberOfRuns);
  694.   writeln;
  695.   writeln ('Execution starts, ', NumberOfRuns : 7, ' runs through Dhrystone');
  696.  
  697.   BeginClock := clock;
  698.  
  699.   (***************)
  700.   (* Start timer *)
  701.   (***************)
  702.   
  703.   for RunIndex := 1 to NumberOfRuns do
  704.   begin
  705.  
  706.     Proc5;
  707.     Proc4;
  708.       (* Char1Glob = 'A', Char2Glob = 'B', BoolGlob = false *)
  709.     Int1Glob := 2;
  710.     Int2Glob := 3;
  711.     String2Glob := 'DHRYSTONE PROGRAM, 2''ND STRING';
  712.     EnumGlob := Ident2;
  713.     BoolGlob := not Func2 (String1Glob, String2Glob);
  714.       (* BoolGlob = true *)
  715.     while Int1Glob < Int2Glob do  (* loop body executed once *)
  716.     begin
  717.       Int3Glob := 5 * Int1Glob - Int2Glob;
  718.         (* Int3Glob = 7 *)
  719.       Proc7 (Int1Glob, Int2Glob, Int3Glob);
  720.         (* Int3Glob = 7 *)
  721.       Int1Glob := Int1Glob + 1;
  722.     end; (* while *)
  723.       (* Int1Glob = 3 *)
  724.     Proc8 (Array1Glob, Array2Glob, Int1Glob, Int3Glob);
  725.       (* IntGlob = 5 *)
  726.     Proc1 (PointerGlob);
  727.     for CharIndex := 'A' to Char2Glob do   (* loop body executed twice *)
  728.       if EnumGlob = Func1 (CharIndex, 'C')
  729.         then (* not executed *)
  730.         begin
  731.           Proc6 (Ident1, EnumGlob);
  732.           String2Glob := 'DHRYSTONE PROGRAM, 3''RD STRING';
  733.           Int2Glob := RunIndex;
  734.           IntGlob := RunIndex;
  735.         end;
  736.     (* Int1Glob = 3, Int2Glob = 3, Int3Glob = 7 *)
  737.     Int2Glob := Int2Glob * Int1Glob;
  738.     Int1Glob := Int2Glob div Int3Glob;
  739.     Int2Glob := 7 * (Int2Glob - Int3Glob) - Int1Glob;
  740.       (* Int1Glob = 1, Int2Glob = 13, Int3Glob = 7 *)
  741.     Proc2 (Int1Glob);
  742.       (* Int1Glob = 5 *)
  743.  
  744.   end; (* for RunIndex *)
  745.  
  746.   EndClock := clock;
  747.  
  748.   (**************)
  749.   (* Stop timer *)
  750.   (**************)
  751.  
  752.   writeln ('Execution ends');
  753.   writeln;
  754.   writeln ('Final values of the variables used in the benchmark:');
  755.   writeln;
  756.  
  757.   writeln ('IntGlob:                      ', IntGlob : 5);
  758.   writeln ('        should be:                5');
  759.   write ('BoolGlob:                      ');
  760.   if BoolGlob = true
  761.   then
  762.     writeln ('TRUE')
  763.   else
  764.     writeln ('FALSE');
  765.   writeln ('        should be:             TRUE');
  766.   writeln ('Char1Glob:                        ', Char1Glob);
  767.   writeln ('        should be:                A');
  768.   writeln ('Char2Glob:                        ', Char2Glob);
  769.   writeln ('        should be:                B');
  770.   writeln ('Array1Glob [8]:               ', Array1Glob [8] : 5);
  771.   writeln ('        should be:                7');
  772.   writeln ('Array2Glob [8,7]:             ', Array2Glob [8,7] : 5);
  773.   writeln ('        should be:                NumberOfRuns + 10');
  774.   writeln ('PointerGlob^.Discr:           ', ord (PointerGlob^.Discr) : 5);
  775.   writeln ('        should be:                0');
  776.   writeln ('PointerGlob^.EnumComp:        ', ord (PointerGlob^.EnumComp) : 5);
  777.   writeln ('        should be:                2');
  778.   writeln ('PointerGlob^.IntComp  :       ', PointerGlob^.IntComp : 5);
  779.   writeln ('        should be:               17');
  780.   write   ('PointerGlob^.StringComp:     ');
  781.   for I := 1 to 30 do
  782.     write (PointerGlob^.StringComp [I]);
  783.   writeln;
  784.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  785.   writeln ('NextPointerGlob^.Discr:       ', ord (NextPointerGlob^.Discr) : 5);
  786.   writeln ('        should be:                0');
  787.   writeln ('NextPointerGlob^.EnumComp:    ',
  788.                     ord (NextPointerGlob^.EnumComp) : 5);
  789.   writeln ('        should be:                1');
  790.   writeln ('NextPointerGlob^.IntComp:     ', NextPointerGlob^.IntComp : 5);
  791.   writeln ('        should be:               18');
  792.   write   ('NextPointerGlob^.StringComp: ');
  793.   for I := 1 to 30 do
  794.     write (NextPointerGlob^.StringComp [I]);
  795.   writeln;
  796.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  797.   writeln ('Int1Glob:                     ', Int1Glob : 5);
  798.   writeln ('        should be:                5');
  799.   writeln ('Int2Glob:                     ', Int2Glob : 5);
  800.   writeln ('        should be:               13');
  801.   writeln ('Int3Glob:                     ', Int3Glob : 5);
  802.   writeln ('        should be:                7');
  803.   writeln ('EnumGlob:                     ', ord (EnumGlob) : 5);
  804.   writeln ('        should be:                1');
  805.   write   ('String1Glob:                 ');
  806.   for I := 1 to 30 do
  807.     write (String1Glob [I]);
  808.   writeln;
  809.   writeln ('        should be:           DHRYSTONE PROGRAM, 1''ST STRING');
  810.   write   ('String2Glob:                 ');
  811.   for I := 1 to 30 do
  812.     write (String2Glob [I]);
  813.   writeln;
  814.   writeln ('        should be:           DHRYSTONE PROGRAM, 2''ND STRING');
  815.   writeln;
  816.   writeln;
  817.  
  818.   SumClocks := EndClock - BeginClock;
  819.  
  820.   if SumClocks < TooSmallTime
  821.     then
  822.     begin
  823.       writeln ('Measured time too small to obtain meaningful results');
  824.       writeln ('Please increase number of runs');
  825.       writeln;
  826.     end
  827.     else
  828.     begin
  829.       Microseconds := SumClocks * (MicrosecondsPerClock / NumberOfRuns);
  830.                                 (* Brackets to prevent integer overflow *)
  831.       DhrystonesPerSecond := NumberOfRuns * (ClocksPerSecond / SumClocks);
  832.       write ('Microseconds for one run through Dhrystone: ');
  833.       writeln (Microseconds : 8 : 1);
  834.       write ('Dhrystones per Second:                      ');
  835.       writeln (DhrystonesPerSecond : 8 : 1);
  836.       writeln;
  837.     end;
  838.   
  839. end.
  840.