diff options
author | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2012-07-04 15:00:52 +0200 |
---|---|---|
committer | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2012-07-04 15:00:52 +0200 |
commit | fd7cbe7b0c0714f43e972074067fe08d79054964 (patch) | |
tree | 1d56b25e7da0586b081476cbdf44bea7c74306cb | |
download | stringbench-fd7cbe7b0c0714f43e972074067fe08d79054964.tar.gz |
stringbench: Add string function benchmarking tools
Change-Id: I695b35d114d4d07900ad82d6f90f09cf5985bf51
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
-rw-r--r-- | Android.mk | 42 | ||||
-rw-r--r-- | dhry.h | 311 | ||||
-rw-r--r-- | dhry_1.c | 774 | ||||
-rw-r--r-- | dhry_2.c | 186 | ||||
-rw-r--r-- | harness.c | 325 | ||||
-rw-r--r-- | stringbench.c | 94 |
6 files changed, 1732 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..dcf06c6 --- /dev/null +++ b/Android.mk @@ -0,0 +1,42 @@ +LOCAL_PATH := $(my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= stringbench.c + +LOCAL_MODULE := stringbench + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) + +LOCAL_MODULE_TAGS := debug + +LOCAL_CFLAGS += -std=gnu99 + +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= harness.c + +LOCAL_MODULE := harness + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) + +LOCAL_MODULE_TAGS := debug + +LOCAL_CFLAGS += -std=gnu99 + +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= dhry_1.c dhry_2.c + +LOCAL_MODULE := dhry + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) + +LOCAL_MODULE_TAGS := debug + +LOCAL_CFLAGS += -I. + +include $(BUILD_EXECUTABLE) @@ -0,0 +1,311 @@ +/*
+ **************************************************************************
+ * DHRYSTONE 2.1 BENCHMARK PC VERSION
+ **************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens AG, AUT E 51
+ * Postfach 3220
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [+49]-9131-7-20330
+ * (8-17 Central European Time)
+ * Usenet: ..!mcsun!unido!estevax!weicker
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ * In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ * are used for execution time measurement. For measurements
+ * on other systems, these calls have to be changed.
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 389-8963 (9-17 EST)
+ * Usenet: ...!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software used.
+ * Hardware information includes: Machine type, CPU, type and size
+ * of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states).
+ * Software information includes: Compiler (and runtime library)
+ * manufacturer and version, compilation switches, OS version.
+ * The Operating System version may give an indication about the
+ * compiler; Dhrystone itself performs no OS calls in the measurement
+ * loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ **************************************************************************
+ *
+ * This version has changes made by Roy Longbottom to conform to a common
+ * format for a series of standard benchmarks for PCs:
+ *
+ * Running time greater than 5 seconds due to inaccuracy of the PC clock.
+ *
+ * Automatic adjustment of run time, no manually inserted parameters.
+ *
+ * Initial display of calibration times to confirm linearity.
+ *
+ * Display of results within one screen (or at a slow speed as the test
+ * progresses) so that it can be seen to have run successfully.
+ *
+ * Facilities to type in details of system used etc.
+ *
+ * All results and details appended to a results file.
+ *
+ *
+ * Roy Longbottom
+ * 101323.2241@compuserve.com
+ *
+ **************************************************************************
+ *
+ * For details of history, changes, other defines, benchmark construction
+ * statistics see official versions from ftp.nosc.mil/pub/aburto where
+ * the latest table of results (dhry.tbl) are available. See also
+ * netlib@ornl.gov
+ *
+ **************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DREG=register (default: Not defined)
+ * As an approximation to what an average C programmer
+ * might do, the "register" storage class is applied
+ * (if enabled by -DREG=register)
+ * - for local variables, if they are used (dynamically)
+ * five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register" declarations
+ * do not necessarily lead to faster execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ ***************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of three files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ * The following "ground rules" apply for measurements:
+ * - Separate compilation
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ * Examples of Pentium Results
+ *
+ * Dhrystone Benchmark Version 2.1 (Language: C)
+ *
+ * Month run 4/1996
+ * PC model Escom
+ * CPU Pentium
+ * Clock MHz 100
+ * Cache 256K
+ * Options Neptune chipset
+ * OS/DOS Windows 95
+ * Compiler Watcom C/ C++ 10.5 Win386
+ * OptLevel -otexan -zp8 -fp5 -5r
+ * Run by Roy Longbottom
+ * From UK
+ * Mail 101323.2241@compuserve.com
+ *
+ * Final values (* implementation-dependent):
+ *
+ * Int_Glob: O.K. 5
+ * Bool_Glob: O.K. 1
+ * Ch_1_Glob: O.K. A
+ * Ch_2_Glob: O.K. B
+ * Arr_1_Glob[8]: O.K. 7
+ * Arr_2_Glob8/7: O.K. 1600010
+ * Ptr_Glob->
+ * Ptr_Comp: * 98008
+ * Discr: O.K. 0
+ * Enum_Comp: O.K. 2
+ * Int_Comp: O.K. 17
+ * Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
+ * Next_Ptr_Glob->
+ * Ptr_Comp: * 98008 same as above
+ * Discr: O.K. 0
+ * Enum_Comp: O.K. 1
+ * Int_Comp: O.K. 18
+ * Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
+ * Int_1_Loc: O.K. 5
+ * Int_2_Loc: O.K. 13
+ * Int_3_Loc: O.K. 7
+ * Enum_Loc: O.K. 1
+ * Str_1_Loc: O.K. DHRYSTONE PROGRAM, 1'ST STRING
+ * Str_2_Loc: O.K. DHRYSTONE PROGRAM, 2'ND STRING
+ *
+ * Register option Selected.
+ *
+ * Microseconds 1 loop: 4.53
+ * Dhrystones / second: 220690
+ * VAX MIPS rating: 125.61
+ *
+ *
+ * Dhrystone Benchmark Version 2.1 (Language: C)
+ *
+ * Month run 4/1996
+ * PC model Escom
+ * CPU Pentium
+ * Clock MHz 100
+ * Cache 256K
+ * Options Neptune chipset
+ * OS/DOS Windows 95
+ * Compiler Watcom C/ C++ 10.5 Win386
+ * OptLevel No optimisation
+ * Run by Roy Longbottom
+ * From UK
+ * Mail 101323.2241@compuserve.com
+ *
+ * Final values (* implementation-dependent):
+ *
+ * Int_Glob: O.K. 5
+ * Bool_Glob: O.K. 1
+ * Ch_1_Glob: O.K. A
+ * Ch_2_Glob: O.K. B
+ * Arr_1_Glob[8]: O.K. 7
+ * Arr_2_Glob8/7: O.K. 320010
+ * Ptr_Glob->
+ * Ptr_Comp: * 98004
+ * Discr: O.K. 0
+ * Enum_Comp: O.K. 2
+ * Int_Comp: O.K. 17
+ * Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
+ * Next_Ptr_Glob->
+ * Ptr_Comp: * 98004 same as above
+ * Discr: O.K. 0
+ * Enum_Comp: O.K. 1
+ * Int_Comp: O.K. 18
+ * Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
+ * Int_1_Loc: O.K. 5
+ * Int_2_Loc: O.K. 13
+ * Int_3_Loc: O.K. 7
+ * Enum_Loc: O.K. 1
+ * Str_1_Loc: O.K. DHRYSTONE PROGRAM, 1'ST STRING
+ * Str_2_Loc: O.K. DHRYSTONE PROGRAM, 2'ND STRING
+ *
+ * Register option Not selected.
+ *
+ * Microseconds 1 loop: 20.06
+ * Dhrystones / second: 49844
+ * VAX MIPS rating: 28.37
+ *
+ **************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#define TIMES
+#endif
+ /* Use times(2) time function unless */
+ /* explicitly defined otherwise */
+
+#ifdef TIMES
+/* #include <sys/types.h>
+ #include <sys/times.h> */
+ /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+#include <string.h>
+
+ /* for strcpy, strcmp */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
+
+
diff --git a/dhry_1.c b/dhry_1.c new file mode 100644 index 0000000..5b5a0a9 --- /dev/null +++ b/dhry_1.c @@ -0,0 +1,774 @@ +/*
+ *************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ *************************************************************************
+ */
+
+ #include <time.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include "dhry.h"
+ /*COMPILER COMPILER COMPILER COMPILER COMPILER COMPILER COMPILER*/
+
+ #ifdef COW
+ #define compiler "Watcom C/C++ 10.5 Win386"
+ #define options " -otexan -zp8 -5r -ms"
+ #endif
+ #ifdef CNW
+ #define compiler "Watcom C/C++ 10.5 Win386"
+ #define options " No optimisation"
+ #endif
+ #ifdef COD
+ #define compiler "Watcom C/C++ 10.5 Dos4GW"
+ #define options " -otexan -zp8 -5r -ms"
+ #endif
+ #ifdef CND
+ #define compiler "Watcom C/C++ 10.5 Dos4GW"
+ #define options " No optimisation"
+ #endif
+ #ifdef CONT
+ #define compiler "Watcom C/C++ 10.5 Win32NT"
+ #define options " -otexan -zp8 -5r -ms"
+ #endif
+ #ifdef CNNT
+ #define compiler "Watcom C/C++ 10.5 Win32NT"
+ #define options " No optimisation"
+ #endif
+ #ifdef COO2
+ #define compiler "Watcom C/C++ 10.5 OS/2-32"
+ #define options " -otexan -zp8 -5r -ms"
+ #endif
+ #ifdef CNO2
+ #define compiler "Watcom C/C++ 10.5 OS/2-32"
+ #define options " No optimisation"
+ #endif
+
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+ Boolean Bool_Glob;
+ char Ch_1_Glob,
+ Ch_2_Glob;
+ int Arr_1_Glob [50];
+ int Arr_2_Glob [50] [50];
+ int getinput = 1;
+
+
+ char Reg_Define[100] = "Register option Selected.";
+
+ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val,
+ Capital_Letter Ch_2_Par_Val);
+ /*
+ forward declaration necessary since Enumeration may not simply be int
+ */
+
+ #ifndef ROPT
+ #define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+ #else
+ #define REG register
+ #endif
+
+ void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+ void Proc_2 (One_Fifty *Int_Par_Ref);
+ void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+ void Proc_4 ();
+ void Proc_5 ();
+ void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par);
+ void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
+ One_Fifty *Int_Par_Ref);
+ void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref,
+ int Int_1_Par_Val, int Int_2_Par_Val);
+
+ Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
+
+
+ /* variables for time measurement: */
+
+ #define Too_Small_Time 2
+ /* Measurements should last at least 2 seconds */
+
+ double Begin_Time,
+ End_Time,
+ User_Time;
+
+ double Microseconds,
+ Dhrystones_Per_Second,
+ Vax_Mips;
+
+ /* end of variables for time measurement */
+
+
+ void main (int argc, char *argv[])
+ /*****/
+
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+ {
+ double dtime();
+
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+ REG int Run_Index;
+ REG int Number_Of_Runs;
+ int endit, count = 10;
+ FILE *Ap;
+ char general[9][80] = {" "};
+
+ /* Initializations */
+ if (argc > 1)
+ {
+ switch (argv[1][0])
+ {
+ case 'N':
+ getinput = 0;
+ break;
+ case 'n':
+ getinput = 0;
+ break;
+ }
+ }
+
+ if ((Ap = fopen("Dhry.txt","a+")) == NULL)
+ {
+ printf("Can not open Dhry.txt\n\n");
+ printf("Press any key\n");
+ exit(1);
+ }
+
+/***********************************************************************
+ * Change for compiler and optimisation used *
+ ***********************************************************************/
+
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C or C++)\n");
+ printf ("\n");
+
+ if (getinput == 0)
+ {
+ printf ("No run time input data\n\n");
+ }
+ else
+ {
+ printf ("With run time input data\n\n");
+ }
+
+ #ifdef ROPT
+ printf ("Register option selected\n\n");
+ #else
+ printf ("Register option not selected\n\n");
+ strcpy(Reg_Define, "Register option Not selected.");
+ #endif
+
+ /*
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+ printf ("Execution starts, %d runs through Dhrystone\n",
+ Number_Of_Runs);
+ */
+
+ Number_Of_Runs = 5000;
+
+ do
+ {
+
+ Number_Of_Runs = Number_Of_Runs * 2;
+ count = count - 1;
+ Arr_2_Glob [8][7] = 10;
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+ Begin_Time = dtime();
+
+ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+ Proc_1 (Ptr_Glob);
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+ }
+ }
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc / Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+ /* Int_1_Loc == 5 */
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+
+ End_Time = dtime();
+ User_Time = End_Time - Begin_Time;
+
+ printf ("%12.0f runs %6.2f seconds \n",(double) Number_Of_Runs, User_Time);
+ if (User_Time > 5)
+ {
+ count = 0;
+ }
+ else
+ {
+ if (User_Time < 0.1)
+ {
+ Number_Of_Runs = Number_Of_Runs * 5;
+ }
+ }
+ } /* calibrate/run do while */
+ while (count >0);
+
+ printf ("\n");
+ printf ("Final values (* implementation-dependent):\n");
+ printf ("\n");
+ printf ("Int_Glob: ");
+ if (Int_Glob == 5) printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Int_Glob);
+
+ printf ("Bool_Glob: ");
+ if (Bool_Glob == 1) printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d\n", Bool_Glob);
+
+ printf ("Ch_1_Glob: ");
+ if (Ch_1_Glob == 'A') printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%c ", Ch_1_Glob);
+
+ printf ("Ch_2_Glob: ");
+ if (Ch_2_Glob == 'B') printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%c\n", Ch_2_Glob);
+
+ printf ("Arr_1_Glob[8]: ");
+ if (Arr_1_Glob[8] == 7) printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Arr_1_Glob[8]);
+
+ printf ("Arr_2_Glob8/7: ");
+ if (Arr_2_Glob[8][7] == Number_Of_Runs + 10)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%10d\n", Arr_2_Glob[8][7]);
+
+ printf ("Ptr_Glob-> ");
+ printf (" Ptr_Comp: * %d\n", (int) Ptr_Glob->Ptr_Comp);
+
+ printf (" Discr: ");
+ if (Ptr_Glob->Discr == 0) printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Ptr_Glob->Discr);
+
+ printf ("Enum_Comp: ");
+ if (Ptr_Glob->variant.var_1.Enum_Comp == 2)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+
+ printf (" Int_Comp: ");
+ if (Ptr_Glob->variant.var_1.Int_Comp == 17) printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Ptr_Glob->variant.var_1.Int_Comp);
+
+ printf ("Str_Comp: ");
+ if (strcmp(Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING") == 0)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%s\n", Ptr_Glob->variant.var_1.Str_Comp);
+
+ printf ("Next_Ptr_Glob-> ");
+ printf (" Ptr_Comp: * %d", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" same as above\n");
+
+ printf (" Discr: ");
+ if (Next_Ptr_Glob->Discr == 0)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Next_Ptr_Glob->Discr);
+
+ printf ("Enum_Comp: ");
+ if (Next_Ptr_Glob->variant.var_1.Enum_Comp == 1)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+
+ printf (" Int_Comp: ");
+ if (Next_Ptr_Glob->variant.var_1.Int_Comp == 18)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Next_Ptr_Glob->variant.var_1.Int_Comp);
+
+ printf ("Str_Comp: ");
+ if (strcmp(Next_Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING") == 0)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%s\n", Next_Ptr_Glob->variant.var_1.Str_Comp);
+
+ printf ("Int_1_Loc: ");
+ if (Int_1_Loc == 5)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Int_1_Loc);
+
+ printf ("Int_2_Loc: ");
+ if (Int_2_Loc == 13)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d\n", Int_2_Loc);
+
+ printf ("Int_3_Loc: ");
+ if (Int_3_Loc == 7)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d ", Int_3_Loc);
+
+ printf ("Enum_Loc: ");
+ if (Enum_Loc == 1)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%d\n", Enum_Loc);
+
+ printf ("Str_1_Loc: ");
+ if (strcmp(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING") == 0)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%s\n", Str_1_Loc);
+
+ printf ("Str_2_Loc: ");
+ if (strcmp(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING") == 0)
+ printf ("O.K. ");
+ else printf ("WRONG ");
+ printf ("%s\n", Str_2_Loc);
+
+ printf ("\n");
+
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+ Microseconds = User_Time * Mic_secs_Per_Second
+ / (double) Number_Of_Runs;
+ Dhrystones_Per_Second = (double) Number_Of_Runs / User_Time;
+ Vax_Mips = Dhrystones_Per_Second / 1757.0;
+
+ printf ("Microseconds for one run through Dhrystone: ");
+ printf ("%12.2lf \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%10.0lf \n", Dhrystones_Per_Second);
+ printf ("VAX MIPS rating = ");
+ printf ("%12.2lf \n",Vax_Mips);
+ printf ("\n");
+
+/************************************************************************
+ * Type details of hardware, software etc. *
+ ************************************************************************/
+
+ if (getinput == 1)
+ {
+ printf ("Enter the following which will be added with results to file DHRY.TXT\n");
+ printf ("When submitting a number of results you need only provide details once\n");
+ printf ("but a cross reference such as an abbreviated CPU type would be useful.\n");
+ printf ("You can kill (exit or close) the program now and no data will be added.\n\n");
+
+ printf ("PC Supplier/model ? ");
+ gets(general[1]);
+
+ printf ("CPU chip ? ");
+ gets(general[2]);
+
+ printf ("Clock MHz ? ");
+ gets(general[3]);
+
+ printf ("Cache size ? ");
+ gets(general[4]);
+
+ printf ("Chipset & H/W options ? ");
+ gets(general[5]);
+
+ printf ("OS/DOS version ? ");
+ gets(general[6]);
+
+ printf ("Your name ? ");
+ gets(general[7]);
+
+ printf ("Company/Location ? ");
+ gets(general[8]);
+
+ printf ("E-mail address ? ");
+ gets(general[0]);
+ }
+/************************************************************************
+ * Add results to output file Dhry.txt *
+ ************************************************************************/
+ fprintf (Ap, "-------------------- -----------------------------------"
+ "\n");
+ fprintf (Ap, "Dhrystone Benchmark Version 2.1 (Language: C++)\n\n");
+ fprintf (Ap, "PC model %s\n", general[1]);
+ fprintf (Ap, "CPU %s\n", general[2]);
+ fprintf (Ap, "Clock MHz %s\n", general[3]);
+ fprintf (Ap, "Cache %s\n", general[4]);
+ fprintf (Ap, "Options %s\n", general[5]);
+ fprintf (Ap, "OS/DOS %s\n", general[6]);
+ fprintf (Ap, "Run by %s\n", general[7]);
+ fprintf (Ap, "From %s\n", general[8]);
+ fprintf (Ap, "Mail %s\n\n", general[0]);
+
+ fprintf (Ap, "Final values (* implementation-dependent):\n");
+ fprintf (Ap, "\n");
+ fprintf (Ap, "Int_Glob: ");
+ if (Int_Glob == 5) fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Int_Glob);
+
+ fprintf (Ap, "Bool_Glob: ");
+ if (Bool_Glob == 1) fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Bool_Glob);
+
+ fprintf (Ap, "Ch_1_Glob: ");
+ if (Ch_1_Glob == 'A') fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%c\n", Ch_1_Glob);
+
+ fprintf (Ap, "Ch_2_Glob: ");
+ if (Ch_2_Glob == 'B') fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%c\n", Ch_2_Glob);
+
+ fprintf (Ap, "Arr_1_Glob[8]: ");
+ if (Arr_1_Glob[8] == 7) fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Arr_1_Glob[8]);
+
+ fprintf (Ap, "Arr_2_Glob8/7: ");
+ if (Arr_2_Glob[8][7] == Number_Of_Runs + 10)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%10d\n", Arr_2_Glob[8][7]);
+
+ fprintf (Ap, "Ptr_Glob-> \n");
+ fprintf (Ap, " Ptr_Comp: * %d\n", (int) Ptr_Glob->Ptr_Comp);
+
+ fprintf (Ap, " Discr: ");
+ if (Ptr_Glob->Discr == 0) fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Ptr_Glob->Discr);
+
+ fprintf (Ap, " Enum_Comp: ");
+ if (Ptr_Glob->variant.var_1.Enum_Comp == 2)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+
+ fprintf (Ap, " Int_Comp: ");
+ if (Ptr_Glob->variant.var_1.Int_Comp == 17) fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Ptr_Glob->variant.var_1.Int_Comp);
+
+ fprintf (Ap, " Str_Comp: ");
+ if (strcmp(Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING") == 0)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%s\n", Ptr_Glob->variant.var_1.Str_Comp);
+
+ fprintf (Ap, "Next_Ptr_Glob-> \n");
+ fprintf (Ap, " Ptr_Comp: * %d", (int) Next_Ptr_Glob->Ptr_Comp);
+ fprintf (Ap, " same as above\n");
+
+ fprintf (Ap, " Discr: ");
+ if (Next_Ptr_Glob->Discr == 0)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Next_Ptr_Glob->Discr);
+
+ fprintf (Ap, " Enum_Comp: ");
+ if (Next_Ptr_Glob->variant.var_1.Enum_Comp == 1)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+
+ fprintf (Ap, " Int_Comp: ");
+ if (Next_Ptr_Glob->variant.var_1.Int_Comp == 18)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+
+ fprintf (Ap, " Str_Comp: ");
+ if (strcmp(Next_Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING") == 0)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%s\n", Next_Ptr_Glob->variant.var_1.Str_Comp);
+
+ fprintf (Ap, "Int_1_Loc: ");
+ if (Int_1_Loc == 5)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Int_1_Loc);
+
+ fprintf (Ap, "Int_2_Loc: ");
+ if (Int_2_Loc == 13)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Int_2_Loc);
+
+ fprintf (Ap, "Int_3_Loc: ");
+ if (Int_3_Loc == 7)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Int_3_Loc);
+
+ fprintf (Ap, "Enum_Loc: ");
+ if (Enum_Loc == 1)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%d\n", Enum_Loc);
+
+ fprintf (Ap, "Str_1_Loc: ");
+ if (strcmp(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING") == 0)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%s\n", Str_1_Loc);
+
+ fprintf (Ap, "Str_2_Loc: ");
+ if (strcmp(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING") == 0)
+ fprintf (Ap, "O.K. ");
+ else fprintf (Ap, "WRONG ");
+ fprintf (Ap, "%s\n", Str_2_Loc);
+
+
+ fprintf (Ap, "\n");
+ fprintf(Ap,"%s\n",Reg_Define);
+ fprintf (Ap, "\n");
+ fprintf(Ap,"Microseconds 1 loop: %12.2lf\n",Microseconds);
+ fprintf(Ap,"Dhrystones / second: %10.0lf\n",Dhrystones_Per_Second);
+ fprintf(Ap,"VAX MIPS rating: %12.2lf\n\n",Vax_Mips);
+ fclose(Ap);
+ }
+
+ printf ("\n");
+ printf ("A new results file will have been created in the same directory as the\n");
+ printf (".EXE files if one did not already exist. If you made a mistake on input, \n");
+ printf ("you can use a text editor to correct it, delete the results or copy \n");
+ printf ("them to a different file name. If you intend to run multiple tests you\n");
+ printf ("you may wish to rename DHRY.TXT with a more informative title.\n\n");
+ printf ("Please submit feedback and results files as a posting in Section 12\n");
+ printf ("or to Roy_Longbottom@compuserve.com\n\n");
+
+ if (getinput == 1)
+ {
+ printf("Press any key to exit\n");
+ printf ("\nIf this is displayed you must close the window in the normal way\n");
+ }
+ }
+
+
+ void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
+ /******************/
+
+ /* executed once */
+ {
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+ structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3 (&Next_Record->Ptr_Comp);
+ /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+ == Ptr_Glob->Ptr_Comp */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ }
+ else /* not executed */
+ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+ } /* Proc_1 */
+
+
+ void Proc_2 (One_Fifty *Int_Par_Ref)
+ /******************/
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+
+ {
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc;
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1); /* true */
+ } /* Proc_2 */
+
+
+ void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+ /******************/
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+
+ {
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+ } /* Proc_3 */
+
+
+void Proc_4 () /* without parameters */
+ /*******/
+ /* executed once */
+ {
+ Boolean Bool_Loc;
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+ } /* Proc_4 */
+
+
+ void Proc_5 () /* without parameters */
+ /*******/
+ /* executed once */
+ {
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+ } /* Proc_5 */
+
+
+ /* Procedure for the assignment of structures, */
+ /* if the C compiler doesn't support this feature */
+ #ifdef NOSTRUCTASSIGN
+ memcpy (d, s, l)
+ register char *d;
+ register char *s;
+ register int l;
+ {
+ while (l--) *d++ = *s++;
+ }
+ #endif
+
+
+double dtime()
+{
+
+ /* #include <ctype.h> */
+
+ #define HZ CLOCKS_PER_SEC
+ clock_t tnow;
+
+ double q;
+ tnow = clock();
+ q = (double)tnow / (double)HZ;
+ return q;
+}
diff --git a/dhry_2.c b/dhry_2.c new file mode 100644 index 0000000..74cb65b --- /dev/null +++ b/dhry_2.c @@ -0,0 +1,186 @@ + /*
+ *************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ *************************************************************************
+ */
+
+ #include "dhry.h"
+
+ #ifndef REG
+ #define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+ #else
+ #define REG register
+ #endif
+
+ extern int Int_Glob;
+ extern char Ch_1_Glob;
+
+ Boolean Func_3 (Enumeration Enum_Par_Val);
+
+ void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+ /*********************************/
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+ {
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (! Func_3 (Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par)
+ {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4: break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+ } /* Proc_6 */
+
+
+ void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
+ One_Fifty *Int_Par_Ref)
+ /**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+
+ {
+ One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+ } /* Proc_7 */
+
+
+ void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref,
+ int Int_1_Par_Val, int Int_2_Par_Val)
+ /*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+
+ {
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+ Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+ Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+ Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+ Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+ Int_Glob = 5;
+ } /* Proc_8 */
+
+
+ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val,
+ Capital_Letter Ch_2_Par_Val)
+ /*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+
+ {
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else /* not executed */
+ {
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+ } /* Func_1 */
+
+
+ Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
+ /*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+ {
+ REG One_Thirty Int_Loc;
+ Capital_Letter Ch_Loc;
+
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1 (Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else /* executed */
+ {
+ if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ }
+ else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+ } /* Func_2 */
+
+
+ Boolean Func_3 (Enumeration Enum_Par_Val)
+ /***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+
+ {
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+ } /* Func_3 */
diff --git a/harness.c b/harness.c new file mode 100644 index 0000000..846e7e9 --- /dev/null +++ b/harness.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2011, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Linaro nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** A simple harness that times how long a string function takes to + * run. + */ + +/* PENDING: Add EPL */ + +#include <string.h> +#include <time.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <assert.h> +#include <unistd.h> +#include <assert.h> + +#define NUM_ELEMS(_x) (sizeof(_x) / sizeof((_x)[0])) + +#ifndef VERSION +#define VERSION "(unknown version)" +#endif + +/** Make sure a function is called by using the return value */ +#define SPOIL(_x) volatile int x = (int)(_x); (void)x + +/** Type of functions that can be tested */ +typedef void (*stub_t)(void *dest, void *src, size_t n); + +/** Meta data about one test */ +struct test +{ + /** Test name */ + const char *name; + /** Function to test */ + stub_t stub; +}; + +/** Flush the cache by reading a chunk of memory */ +static void empty(volatile char *against) +{ + /* We know that there's a 16 k cache with 64 byte lines giving + a total of 256 lines. Read randomly from 256*5 places should + flush everything */ + int offset = (1024 - 256)*1024; + + for (int i = offset; i < offset + 16*1024*3; i += 64) + { + against[i]; + } +} + +/** Stub that does nothing. Used for calibrating */ +static void xbounce(void *dest, void *src, size_t n) +{ + SPOIL(0); +} + +/** Stub that calls memcpy */ +static void xmemcpy(void *dest, void *src, size_t n) +{ + SPOIL(memcpy(dest, src, n)); +} + +/** Stub that calls memset */ +static void xmemset(void *dest, void *src, size_t n) +{ + SPOIL(memset(dest, 0, n)); +} + +/** Stub that calls strcpy */ +static void xstrcpy(void *dest, void *src, size_t n) +{ + SPOIL(strcpy(dest, src)); +} + +/** Stub that calls strlen */ +static void xstrlen(void *dest, void *src, size_t n) +{ + SPOIL(strlen(dest)); +} + +/** Stub that calls strcmp */ +static void xstrcmp(void *dest, void *src, size_t n) +{ + SPOIL(strcmp(dest, src)); +} + +/** Stub that calls strchr */ +static void xstrchr(void *dest, void *src, size_t n) +{ + /* Put the character at the end of the string and before the null */ + ((char *)src)[n-1] = 32; + SPOIL(strchr(src, 32)); +} + +/** Stub that calls memchr */ +static void xmemchr(void *dest, void *src, size_t n) +{ + /* Put the character at the end of the block */ + ((char *)src)[n-1] = 32; + SPOIL(memchr(src, 32, n)); +} + +/** All functions that can be tested */ +static const struct test tests[] = + { + { "bounce", xbounce }, + { "memchr", xmemchr }, + { "memcpy", xmemcpy }, + { "memset", xmemset }, + { "strchr", xstrchr }, + { "strcmp", xstrcmp }, + { "strcpy", xstrcpy }, + { "strlen", xstrlen }, + { NULL } + }; + +/** Show basic usage */ +static void usage(const char* name) +{ + printf("%s %s: run a string related benchmark.\n" + "usage: %s [-c block-size] [-l loop-count] [-a alignment] [-f] [-t test-name]\n" + , name, VERSION, name); + + printf("Tests:"); + + for (const struct test *ptest = tests; ptest->name != NULL; ptest++) + { + printf(" %s", ptest->name); + } + + printf("\n"); + + exit(-1); +} + +/** Find the test by name */ +static const struct test *find_test(const char *name) +{ + if (name == NULL) + { + return tests + 0; + } + else + { + for (const struct test *p = tests; p->name != NULL; p++) + { + if (strcmp(p->name, name) == 0) + { + return p; + } + } + } + + return NULL; +} + +/** Take a pointer and ensure that the lower bits == alignment */ +static char *realign(char *p, int alignment) +{ + if (alignment < 0) + { + return p; + } + + uintptr_t pp = (uintptr_t)p; + pp = (pp + 255) & ~255; + pp += alignment; + + return (char *)pp; +} + +/** Setup and run a test */ +int main(int argc, char **argv) +{ + /* Buffers to read and write from */ + char *src = calloc(1024, 1024); + char *dest = calloc(1024, 1024); + + assert(src != NULL && dest != NULL); + + /* Number of bytes per call */ + int count = 31; + /* Number of times to run */ + int loops = 10000000; + /* True to flush the cache each time */ + int flush = 0; + /* Name of the test */ + const char *name = NULL; + /* Alignment of both buffers */ + int alignment = -1; + + int opt; + + while ((opt = getopt(argc, argv, "c:l:ft:hva:")) > 0) + { + switch (opt) + { + case 'c': + count = atoi(optarg); + break; + case 'l': + loops = atoi(optarg); + break; + case 'a': + alignment = atoi(optarg); + break; + case 'f': + flush = 1; + break; + case 't': + name = strdup(optarg); + break; + case 'h': + usage(argv[0]); + break; + default: + usage(argv[0]); + break; + } + } + + /* Find the test by name */ + const struct test *ptest = find_test(name); + + if (ptest == NULL) + { + usage(argv[0]); + } + + src = realign(src, alignment); + dest = realign(dest, alignment); + + /* Fill the first 16 k with non-zero, reproducable random data */ + srandom(1539); + + for (int i = 0; i < 16*1024; i++) + { + src[i] = (char)random() | 1; + dest[i] = src[i]; + } + + /* Make sure the buffers are null terminated for any string tests */ + src[count] = 0; + dest[count] = 0; + + struct timespec start, end; + int err = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); + assert(err == 0); + + /* Preload */ + stub_t stub = ptest->stub; + + /* Run two variants to reduce the cost of testing for the flush */ + if (flush == 0) + { + for (int i = 0; i < loops; i++) + { + (*stub)(dest, src, count); + } + } + else + { + for (int i = 0; i < loops; i++) + { + (*stub)(dest, src, count); + empty(dest); + } + } + + err = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); + assert(err == 0); + + /* Drop any leading path and pull the variant name out of the executable */ + char *variant = strrchr(argv[0], '/'); + + if (variant == NULL) + { + variant = argv[0]; + } + + variant = strstr(variant, "try-"); + assert(variant != NULL); + + double elapsed = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) * 1e-9; + /* Estimate the bounce time. Measured on a Panda. */ + double bounced = 0.448730 * loops / 50000000; + + /* Dump both machine and human readable versions */ + printf("%s:%s:%u:%u:%d:%.6f: took %.6f s for %u calls to %s of %u bytes. ~%.3f MB/s corrected.\n", + variant + 4, ptest->name, + count, loops, alignment, + elapsed, + elapsed, loops, ptest->name, count, + (double)loops*count/(elapsed - bounced)/(1024*1024)); + + return 0; +} diff --git a/stringbench.c b/stringbench.c new file mode 100644 index 0000000..392ef37 --- /dev/null +++ b/stringbench.c @@ -0,0 +1,94 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/time.h> + +#define START gettimeofday(&tv1, 0); +#define END(x) gettimeofday(&tv2, 0); t1 = ((double)tv1.tv_sec)+((double)tv1.tv_usec)/1000000.0; t2 = ((double)tv2.tv_sec)+((double)tv2.tv_usec)/1000000.0; printf("%s: %f seconds\n", x, t2-t1) + +int main(int argc, char **argv) { + struct timeval tv1, tv2; + double t1, t2; + char * const s = (char * const) malloc(16); + char * const l = (char * const) malloc(15001); + char * const tmp = (char * const) malloc(15001); + + for(int i=0; i<15; i++) + s[i]='a'; + s[15]=0; + + START; + for(int i=0; i<10000000; i++) { + memset(l, 'a', 15000); + } + END("10000000 * memset 15000*'a'"); + + l[15000]=0; + + START; + for(int i=0; i<500000000; i++) + if(strlen(s) != 15) + fprintf(stderr, "strlen broken\n"); + END("500000000 * strlen(15*a)"); + + START; + for(int i=0; i<1000000; i++) + if(strlen(l) != 15000) + fprintf(stderr, "strlen broken\n"); + END("1000000 * strlen(15000*a)"); + + START; + for(int i=0; i<10000000; i++) + if(memchr(l, 'b', 15000)) + fprintf(stderr, "bogus memchr\n"); + END("10000000 * memchr not finding anything in 15000 chars"); + + START; + for(int i=0; i<10000000; i++) + if(strchr(l, 'b')) + fprintf(stderr, "bogus strchr\n"); + END("10000000 * strchr not finding anything in 15000 chars"); + + l[5000]='b'; + START; + for(int i=0; i<10000000; i++) { + char *b=memchr(l, 'b', 15000); + if(!b || *b != 'b') + fprintf(stderr, "bogus memchr II\n"); + } + END("10000000 * memchr finding match at 5000"); + + START; + for(int i=0; i<10000000; i++) { + char *b=strchr(l, 'b'); + if(!b || *b != 'b') + fprintf(stderr, "bogus strchr II\n"); + } + END("10000000 * strchr finding match at 5000"); + + START; + for(int i=0; i<10000000; i++) { + memcpy(tmp, l, 15000); + } + END("10000000 * memcpy of 15000 bytes"); + + START; + for(int i=0; i<900000000; i++) { + memcpy(tmp, s, 15); + } + END("900000000 * memcpy of 15 bytes"); + + START; + for(int i=0; i<1000000; i++) { + strcpy(tmp, l); + } + END("1000000 * strcpy of 15000 bytes"); + + START; + for(int i=0; i<100000000; i++) { + strcpy(tmp, s); + } + END("100000000 * strcpy of 15 bytes"); + + return 0; +} |