summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-07-04 15:00:52 +0200
committerBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-07-04 15:00:52 +0200
commitfd7cbe7b0c0714f43e972074067fe08d79054964 (patch)
tree1d56b25e7da0586b081476cbdf44bea7c74306cb
downloadstringbench-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.mk42
-rw-r--r--dhry.h311
-rw-r--r--dhry_1.c774
-rw-r--r--dhry_2.c186
-rw-r--r--harness.c325
-rw-r--r--stringbench.c94
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)
diff --git a/dhry.h b/dhry.h
new file mode 100644
index 0000000..69b8526
--- /dev/null
+++ b/dhry.h
@@ -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;
+}