From 1fa9357768c1b4b2301b7341656dbc81e531c9f6 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Tue, 11 Nov 2008 22:34:57 +0000 Subject: -- Split nbench1.c into component files -- Combine wordcat.h with huffman routines in huffman.c -- Readd NNET.DAT (oops) -- Update Makefile to build component files git-svn-id: svn://mattst88.com/svn/cleanbench/trunk@3 0d43b9a7-5ab2-4d7b-af9d-f64450cef757 --- Makefile | 129 +- NNET.DAT | 210 +++ assignment.c | 562 ++++++++ bitfield.c | 335 +++++ emfloat.h | 4 - fourier.c | 302 ++++ fpemulation.c | 147 ++ huffman.c | 557 ++++++++ idea.c | 392 +++++ linear.c | 541 +++++++ nbench0.h | 2 - nbench1.c | 4445 --------------------------------------------------------- nbench1.h | 428 ------ neural.c | 815 +++++++++++ nmglobal.h | 3 - numsort.c | 292 ++++ stringsort.c | 575 ++++++++ wordcat.h | 81 -- 18 files changed, 4813 insertions(+), 5007 deletions(-) create mode 100644 NNET.DAT create mode 100644 assignment.c create mode 100644 bitfield.c create mode 100644 fourier.c create mode 100644 fpemulation.c create mode 100644 huffman.c create mode 100644 idea.c create mode 100644 linear.c delete mode 100644 nbench1.c delete mode 100644 nbench1.h create mode 100644 neural.c create mode 100644 numsort.c create mode 100644 stringsort.c delete mode 100644 wordcat.h diff --git a/Makefile b/Makefile index 5045c77..311e55d 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,16 @@ default: nbench # You should leave -static in the CFLAGS so that your sysinfo can be # compiled into the executable. -CC = gcc +CCC=gcc +GCC=gcc # generic options for gcc -CFLAGS = -s -static -Wall -O3 +#CFLAGS=-O3 -mcpu=ev67 -mieee -funroll-loops -ftree-vectorize -fprefetch-loop-arrays -pipe -static -msmall-data -msmall-text +#CFLAGS=-O3 -mcpu=ev67 -mieee -pipe -msmall-data -msmall-text -funroll-loops -ftree-vectorize -static +GCCFLAGS=-O3 -march=k8 -msse3 -ftree-vectorize -funroll-loops -pipe +#CCCFLAGS=-fast -unroll 0 -inline speed +CCCFLAGS=${GCCFLAGS} +LINKFLAGS= # if your gcc lets you do it, then try this one #CFLAGS = -s -static -Wall -O3 -fomit-frame-pointer -funroll-loops @@ -91,15 +97,15 @@ MACHINE= # For any Unix flavor you need -DLINUX # You also need -DLINUX to get the new indices -DEFINES= -DLINUX $(NO_UNAME) +DEFINES=$(NO_UNAME) -DLINUX ########################################################################## # For LINUX-like systems with gcc sysinfoc.c: Makefile - ./sysinfo.sh $(CC) $(MACHINE) $(DEFINES) $(CFLAGS) + ./sysinfo.sh $(GCC) $(DEFINES) $(GCCFLAGS) sysinfo.c: Makefile - ./sysinfo.sh $(CC) $(MACHINE) $(DEFINES) $(CFLAGS) + ./sysinfo.sh $(GCC) $(DEFINES) $(GCCFLAGS) ########################################################################## # For non-LINUX systems @@ -107,47 +113,82 @@ sysinfo.c: Makefile # and take sysinfo.c and sysinfoc.c out of the dependencies for nbench0.o hardware.o: hardware.c hardware.h Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c hardware.c - -nbench0.o: nbench0.h nbench0.c nmglobal.h pointer.h hardware.h\ - Makefile sysinfo.c sysinfoc.c - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c nbench0.c - -emfloat.o: emfloat.h emfloat.c nmglobal.h pointer.h Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c emfloat.c - -pointer.h: pointer Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -o pointer pointer.c - rm -f pointer.h - if [ "4" = `./pointer` ] ; then touch pointer.h ;\ - else echo "#define LONG64" >pointer.h ; fi - -misc.o: misc.h misc.c Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c misc.c - -nbench1.o: nbench1.h nbench1.c wordcat.h nmglobal.h pointer.h Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c nbench1.c - -sysspec.o: sysspec.h sysspec.c nmglobal.h pointer.h Makefile - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS)\ - -c sysspec.c - -nbench: emfloat.o misc.o nbench0.o nbench1.o sysspec.o hardware.o - $(CC) $(MACHINE) $(DEFINES) $(CFLAGS) $(LINKFLAGS)\ - emfloat.o misc.o nbench0.o nbench1.o sysspec.o hardware.o\ - -o nbench -lm + $(GCC) $(DEFINES) $(GCCFLAGS) -c hardware.c + +nbench0.o: nbench0.h nbench0.c nmglobal.h hardware.h Makefile sysinfo.c sysinfoc.c + $(GCC) $(DEFINES) $(GCCFLAGS) -c nbench0.c +# Segfault before first test + +emfloat.o: emfloat.h emfloat.c nmglobal.h Makefile + $(CCC) $(DEFINES) $(CCCFLAGS) -c emfloat.c + +misc.o: misc.c Makefile + $(CCC) $(DEFINES) $(CCCFLAGS) -c misc.c + +numsort.o: numsort.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c numsort.c +# gcc - 2.95 +# ccc - 5.08 + +stringsort.o: stringsort.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c stringsort.c +# gcc - 6.77 +# ccc - 7.24 + +bitfield.o: bitfield.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c bitfield.c +# gcc - 4.93, 4.90, 4.93, 4.93 +# ccc - 4.79, 4.85, 4.81, + +fpemulation.o: fpemulation.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c fpemulation.c +# gcc - 13.90 +# ccc - 13.90 + +fourier.o: fourier.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c fourier.c +# gcc - 15.96 +# ccc - 19.30 + +assignment.o: assignment.c + $(GCC) $(DEFINES) $(GCCFLAGS) -c assignment.c +# gcc - 16.51 +# ccc - 7.98 + +idea.o: idea.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c idea.c +# gcc - 8.79 +# ccc - 9.10 + +huffman.o: huffman.c + $(GCC) $(DEFINES) $(GCCFLAGS) -c huffman.c +# $(CCC) $(DEFINES) -O1 -host -unroll 0 -inline speed -c huffman.c -g3 +# $(CCC) $(DEFINES) $(CCCFLAGS) -c huffman.c -g3 +# gcc - 6.94 +# ccc - segfault +# ccc -O1 -host - 5.14 +# ccc -O2 -host - segfault +# ccc -O1 -host -unroll 0 -inline speed - 5.95 + +neural.o: neural.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c neural.c +# gcc - 12.00 +# ccc - 14.20 + +linear.o: linear.c + $(CCC) $(DEFINES) $(CCCFLAGS) -c linear.c +# gcc - 16.38 +# ccc - 23.29 + +sysspec.o: sysspec.h sysspec.c nmglobal.h Makefile + $(GCC) $(DEFINES) $(GCCFLAGS) -c sysspec.c + +nbench: emfloat.o misc.o nbench0.o numsort.o sysspec.o hardware.o stringsort.o bitfield.o fpemulation.o fourier.o assignment.o idea.o huffman.o neural.o linear.o + $(GCC) emfloat.o misc.o nbench0.o numsort.o sysspec.o hardware.o stringsort.o bitfield.o fpemulation.o fourier.o assignment.o idea.o huffman.o neural.o linear.o -o nbench -lm ########################################################################## clean: - - /bin/rm -f *.o *~ \#* core a.out hello sysinfo.c sysinfoc.c \ - bug pointer pointer.h debugbit.dat + - /bin/rm -f *.o nbench sysinfo.c sysinfoc.c -mrproper: clean - - /bin/rm -f nbench +remake: clean nbench diff --git a/NNET.DAT b/NNET.DAT new file mode 100644 index 0000000..5711730 --- /dev/null +++ b/NNET.DAT @@ -0,0 +1,210 @@ +5 7 8 +26 +0 0 1 0 0 +0 1 0 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 0 0 0 0 0 1 +1 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 0 +0 1 0 0 0 0 1 0 +0 1 1 1 0 +1 0 0 0 1 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 1 +0 1 1 1 0 +0 1 0 0 0 0 1 1 +1 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 0 +0 1 0 0 0 1 0 0 +1 1 1 1 1 +1 0 0 0 0 +1 0 0 0 0 +1 1 1 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 1 1 1 1 +0 1 0 0 0 1 0 1 +1 1 1 1 1 +1 0 0 0 0 +1 0 0 0 0 +1 1 1 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +0 1 0 0 0 1 1 0 +0 1 1 1 0 +1 0 0 0 1 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 1 1 +1 0 0 0 1 +0 1 1 1 0 +0 1 0 0 0 1 1 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 0 0 1 0 0 0 +0 1 1 1 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 1 1 1 0 +0 1 0 0 1 0 0 1 +0 0 0 0 1 +0 0 0 0 1 +0 0 0 0 1 +0 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 1 1 0 +0 1 0 0 1 0 1 0 +1 0 0 0 1 +1 0 0 1 0 +1 0 1 0 0 +1 1 0 0 0 +1 0 1 0 0 +1 0 0 1 0 +1 0 0 0 1 +0 1 0 0 1 0 1 1 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +1 1 1 1 1 +0 1 0 0 1 1 0 0 +1 0 0 0 1 +1 1 0 1 1 +1 0 1 0 1 +1 0 1 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 0 0 1 1 0 1 +1 0 0 0 1 +1 1 0 0 1 +1 0 1 0 1 +1 0 1 0 1 +1 0 1 0 1 +1 0 0 1 1 +1 0 0 0 1 +0 1 0 0 1 1 1 0 +0 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 1 1 0 +0 1 0 0 1 1 1 1 +1 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 0 +1 0 0 0 0 +1 0 0 0 0 +1 0 0 0 0 +0 1 0 1 0 0 0 0 +0 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 1 0 1 +1 0 0 1 1 +0 1 1 1 1 +0 1 0 1 0 0 0 1 +1 1 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 1 1 1 0 +1 0 1 0 0 +1 0 0 1 0 +1 0 0 0 1 +0 1 0 1 0 0 1 0 +0 1 1 1 1 +1 0 0 0 0 +1 0 0 0 0 +0 1 1 1 0 +0 0 0 0 1 +0 0 0 0 1 +1 1 1 1 0 +0 1 0 1 0 0 1 1 +1 1 1 1 1 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 1 0 1 0 1 0 0 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 1 1 0 +0 1 0 1 0 1 0 1 +1 0 0 0 1 +1 0 0 0 1 +0 1 0 1 0 +0 1 0 1 0 +0 1 0 1 0 +0 1 0 1 0 +0 0 1 0 0 +0 1 0 1 0 1 1 0 +1 0 0 0 1 +1 0 0 0 1 +1 0 0 0 1 +1 0 1 0 1 +1 0 1 0 1 +1 0 1 0 1 +0 1 0 1 0 +0 1 0 1 0 1 1 1 +1 0 0 0 1 +0 1 0 1 0 +0 1 0 1 0 +0 0 1 0 0 +0 1 0 1 0 +0 1 0 1 0 +1 0 0 0 1 +0 1 0 1 1 0 0 0 +1 0 0 0 1 +0 1 0 1 0 +0 1 0 1 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 0 1 0 0 +0 1 0 1 1 0 0 1 +1 1 1 1 1 +0 0 0 1 0 +0 0 0 1 0 +0 0 1 0 0 +0 1 0 0 0 +0 1 0 0 0 +1 1 1 1 1 +0 1 0 1 1 0 1 0 diff --git a/assignment.c b/assignment.c new file mode 100644 index 0000000..7313d78 --- /dev/null +++ b/assignment.c @@ -0,0 +1,562 @@ +#include +#include "nmglobal.h" +#include "nbench1.h" + +/************************* +** ASSIGNMENT ALGORITHM ** +*************************/ + +/************* +** DoAssign ** +************** +** Perform an assignment algorithm. +** The algorithm was adapted from the step by step guide found +** in "Quantitative Decision Making for Business" (Gordon, +** Pressman, and Cohn; Prentice-Hall) +** +** +** NOTES: +** 1. Even though the algorithm distinguishes between +** ASSIGNROWS and ASSIGNCOLS, as though the two might +** be different, it does presume a square matrix. +** I.E., ASSIGNROWS and ASSIGNCOLS must be the same. +** This makes for some algorithmically-correct but +** probably non-optimal constructs. +** +*/ +void DoAssign(void) +{ +AssignStruct *locassignstruct; /* Local structure ptr */ +farlong *arraybase; +char *errorcontext; +int systemerror; +ulong accumtime; +double iterations; + +/* +** Link to global structure +*/ +locassignstruct=&global_assignstruct; + +/* +** Set the error context string. +*/ +errorcontext="CPU:Assignment"; + +/* +** See if we need to do self adjustment code. +*/ +if(locassignstruct->adjust==0) +{ + /* + ** Self-adjustment code. The system begins by working on 1 + ** array. If it does that in no time, then two arrays + ** are built. This process continues until + ** enough arrays are built to handle the tolerance. + */ + locassignstruct->numarrays=1; + while(1) + { + /* + ** Allocate space for arrays + */ + arraybase=(farlong *) AllocateMemory(sizeof(long)* + ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays, + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((farvoid *)arraybase, + &systemerror); + ErrorExit(); + } + + /* + ** Do an iteration of the assignment alg. If the + ** elapsed time is less than or equal to the permitted + ** minimum, then allocate for more arrays and + ** try again. + */ + if(DoAssignIteration(arraybase, + locassignstruct->numarrays)>global_min_ticks) + break; /* We're ok...exit */ + + FreeMemory((farvoid *)arraybase, &systemerror); + locassignstruct->numarrays++; + } +} +else +{ /* + ** Allocate space for arrays + */ + arraybase=(farlong *)AllocateMemory(sizeof(long)* + ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays, + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((farvoid *)arraybase, + &systemerror); + ErrorExit(); + } +} + +/* +** All's well if we get here. Do the tests. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoAssignIteration(arraybase, + locassignstruct->numarrays); + iterations+=(double)1.0; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +FreeMemory((farvoid *)arraybase,&systemerror); + +locassignstruct->iterspersec=iterations * + (double)locassignstruct->numarrays / TicksToFracSecs(accumtime); + +if(locassignstruct->adjust==0) + locassignstruct->adjust=1; + +return; + +} + +/********************** +** DoAssignIteration ** +*********************** +** This routine executes one iteration of the assignment test. +** It returns the number of ticks elapsed in the iteration. +*/ +static ulong DoAssignIteration(farlong *arraybase, + ulong numarrays) +{ +longptr abase; /* local pointer */ +ulong elapsed; /* Elapsed ticks */ +ulong i; + +/* +** Set up local pointer +*/ +abase.ptrs.p=arraybase; + +/* +** Load up the arrays with a random table. +*/ +LoadAssignArrayWithRand(arraybase,numarrays); + +/* +** Start the stopwatch +*/ +elapsed=StartStopwatch(); + +/* +** Execute assignment algorithms +*/ +for(i=0;i1) + for(i=1;i +/* +#include +#include +#include +#include +#include */ +#include "nmglobal.h" +#include "nbench1.h" + +#ifdef DEBUG +static int numsort_status=0; +static int stringsort_status=0; +#endif + +/************************ +** BITFIELD OPERATIONS ** +*************************/ + +/************* +** DoBitops ** +************** +** Perform the bit operations test portion of the CPU +** benchmark. Returns the iterations per second. +*/ +void DoBitops(void) +{ +BitOpStruct *locbitopstruct; /* Local bitop structure */ +unsigned long *bitarraybase; /* Base of bitmap array */ +unsigned long *bitoparraybase; /* Base of bitmap operations array */ +unsigned long nbitops; /* # of bitfield operations */ +unsigned long accumtime; /* Accumulated time in ticks */ +double iterations; /* # of iterations */ +char *errorcontext; /* Error context string */ +int systemerror; /* For holding error codes */ +int ticks; + +/* +** Link to global structure. +*/ +locbitopstruct=&global_bitopstruct; + +/* +** Set the error context. +*/ +errorcontext="CPU:Bitfields"; + +/* +** See if we need to run adjustment code. +*/ +if(locbitopstruct->adjust==0) +{ + bitarraybase=(unsigned long *)AllocateMemory(locbitopstruct->bitfieldarraysize * + sizeof(unsigned long),&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + } + + /* + ** Initialize bitfield operations array to [2,30] elements + */ + locbitopstruct->bitoparraysize=30L; + + while(1) + { + /* + ** Allocate space for operations array + */ + bitoparraybase=(unsigned long *)AllocateMemory(locbitopstruct->bitoparraysize*2L* + sizeof(unsigned long), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)bitarraybase,&systemerror); + } + /* + ** Do an iteration of the bitmap test. If the + ** elapsed time is less than or equal to the permitted + ** minimum, then de-allocate the array, reallocate a + ** larger version, and try again. + */ + ticks=DoBitfieldIteration(bitarraybase, + bitoparraybase, + locbitopstruct->bitoparraysize, + &nbitops); +#ifdef DEBUG +#ifdef LINUX + if (locbitopstruct->bitoparraysize==30L){ + /* this is the first loop, write a debug file */ + FILE *file; + unsigned long *running_base; /* same as unsigned long */ + long counter; + file=fopen("debugbit.dat","w"); + running_base=bitarraybase; + for (counter=0;counter<(long)(locbitopstruct->bitfieldarraysize);counter++){ +#ifdef _LP64 + fprintf(file,"%08X",(unsigned int)(*running_base&0xFFFFFFFFL)); + fprintf(file,"%08X",(unsigned int)((*running_base>>32)&0xFFFFFFFFL)); + if ((counter+1)%4==0) fprintf(file,"\n"); +#else + fprintf(file,"%08lX",*running_base); + if ((counter+1)%8==0) fprintf(file,"\n"); +#endif + running_base=running_base+1; + } + fclose(file); + printf("\nWrote the file debugbit.dat, you may want to compare it to debugbit.good\n"); + } +#endif +#endif + + if (ticks>global_min_ticks) break; /* We're ok...exit */ + + FreeMemory((void *)bitoparraybase,&systemerror); + locbitopstruct->bitoparraysize+=100L; + } +} +else +{ + /* + ** Don't need to do self adjustment, just allocate + ** the array space. + */ + bitarraybase=(unsigned long *)AllocateMemory(locbitopstruct->bitfieldarraysize * + sizeof(unsigned long),&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + } + bitoparraybase=(unsigned long *)AllocateMemory(locbitopstruct->bitoparraysize*2L* + sizeof(unsigned long), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)bitarraybase,&systemerror); + } +} + +/* +** All's well if we get here. Repeatedly perform bitops until the +** accumulated elapsed time is greater than # of seconds requested. +*/ +accumtime=0L; +iterations=(double)0.0; +do { + accumtime+=DoBitfieldIteration(bitarraybase, + bitoparraybase, + locbitopstruct->bitoparraysize,&nbitops); + iterations+=(double)nbitops; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. +** Also, set adjustment flag to show that we don't have +** to do self adjusting in the future. +*/ +FreeMemory((void *)bitarraybase,&systemerror); +FreeMemory((void *)bitoparraybase,&systemerror); +locbitopstruct->bitopspersec=iterations /TicksToFracSecs(accumtime); +if(locbitopstruct->adjust==0) + locbitopstruct->adjust=1; + +return; +} + +/************************ +** DoBitfieldIteration ** +************************* +** Perform a single iteration of the bitfield benchmark. +** Return the # of ticks accumulated by the operation. +*/ +static unsigned long DoBitfieldIteration(unsigned long *bitarraybase, + unsigned long *bitoparraybase, + long bitoparraysize, + unsigned long *nbitops) +{ +long i; /* Index */ +unsigned long bitoffset; /* Offset into bitmap */ +unsigned long elapsed; /* Time to execute */ +/* +** Clear # bitops counter +*/ +*nbitops=0L; + +/* +** Construct a set of bitmap offsets and run lengths. +** The offset can be any random number from 0 to the +** size of the bitmap (in bits). The run length can +** be any random number from 1 to the number of bits +** between the offset and the end of the bitmap. +** Note that the bitmap has 8192 * 32 bits in it. +** (262,144 bits) +*/ +/* +** Reset random number generator so things repeat. +** Also reset the bit array we work on. +** added by Uwe F. Mayer +*/ +randnum((int32_t)13); + +for (i=0;i>6; /* Index is number /64 */ + bitnumb=bit_addr % 64; /* Bit number in longword */ +#else + bindex=bit_addr>>5; /* Index is number /32 */ + bitnumb=bit_addr % 32; /* Bit number in longword */ +#endif + bitmap[bindex]^=(1L<> 6; /* Index is number /64 */ + bitnumb = bit_addr % 64; /* Bit number in word */ + + if (val) { + bitmap[bindex] |= (1L << bitnumb); + } else { + bitmap[bindex] &= ~(1L << bitnumb); + } + bit_addr++; + } +#else + if (val) { + for (; nbits != 0; nbits--) { + bindex = bit_addr >> 6; + bitnumb = bit_addr % 64; + + bitmap[bindex] |= (1L << bitnumb); + + bit_addr++; + } + } else { + for (; nbits != 0; nbits--) { + bindex = bit_addr >> 6; + bitnumb = bit_addr % 64; + + bitmap[bindex] &= ~(1L << bitnumb); + + bit_addr++; + } + } +#endif + return; +} diff --git a/emfloat.h b/emfloat.h index 41cc6d9..7699c1e 100644 --- a/emfloat.h +++ b/emfloat.h @@ -27,10 +27,6 @@ #include -/* Is this a 64 bit architecture? If so, this will define LONG64 */ -/* Uwe F. Mayer 15 November 1997 */ -#include "pointer.h" - /* ** DEFINES */ diff --git a/fourier.c b/fourier.c new file mode 100644 index 0000000..1c95cb7 --- /dev/null +++ b/fourier.c @@ -0,0 +1,302 @@ +/* +#include +#include +#include +#include */ +#include +#include "nmglobal.h" +#include "nbench1.h" + +/************************* +** FOURIER COEFFICIENTS ** +*************************/ + +/************** +** DoFourier ** +*************** +** Perform the transcendental/trigonometric portion of the +** benchmark. This benchmark calculates the first n +** fourier coefficients of the function (x+1)^x defined +** on the interval 0,2. +*/ +void DoFourier(void) +{ +FourierStruct *locfourierstruct; /* Local fourier struct */ +fardouble *abase; /* Base of A[] coefficients array */ +fardouble *bbase; /* Base of B[] coefficients array */ +unsigned long accumtime; /* Accumulated time in ticks */ +double iterations; /* # of iterations */ +char *errorcontext; /* Error context string pointer */ +int systemerror; /* For error code */ + +/* +** Link to global structure +*/ +locfourierstruct=&global_fourierstruct; + +/* +** Set error context string +*/ +errorcontext="FPU:Transcendental"; + +/* +** See if we need to do self-adjustment code. +*/ +if(locfourierstruct->adjust==0) +{ + locfourierstruct->arraysize=100L; /* Start at 100 elements */ + while(1) + { + + abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + ErrorExit(); + } + + bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)abase,&systemerror); + ErrorExit(); + } + /* + ** Do an iteration of the tests. If the elapsed time is + ** less than or equal to the permitted minimum, re-allocate + ** larger arrays and try again. + */ + if(DoFPUTransIteration(abase,bbase, + locfourierstruct->arraysize)>global_min_ticks) + break; /* We're ok...exit */ + + /* + ** Make bigger arrays and try again. + */ + FreeMemory((farvoid *)abase,&systemerror); + FreeMemory((farvoid *)bbase,&systemerror); + locfourierstruct->arraysize+=50L; + } +} +else +{ /* + ** Don't need self-adjustment. Just allocate the + ** arrays, and go. + */ + abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + ErrorExit(); + } + + bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)abase,&systemerror); + ErrorExit(); + } +} +/* +** All's well if we get here. Repeatedly perform integration +** tests until the accumulated time is greater than the +** # of seconds requested. +*/ +accumtime=0L; +iterations=(double)0.0; +do { + accumtime+=DoFPUTransIteration(abase,bbase,locfourierstruct->arraysize); + iterations+=(double)locfourierstruct->arraysize*(double)2.0-(double)1.0; +} while(TicksToSecs(accumtime)request_secs); + + +/* +** Clean up, calculate results, and go home. +** Also set adjustment flag to indicate no adjust code needed. +*/ +FreeMemory((farvoid *)abase,&systemerror); +FreeMemory((farvoid *)bbase,&systemerror); + +locfourierstruct->fflops=iterations/(double)TicksToFracSecs(accumtime); + +if(locfourierstruct->adjust==0) + locfourierstruct->adjust=1; + +return; +} + +/************************ +** DoFPUTransIteration ** +************************* +** Perform an iteration of the FPU Transcendental/trigonometric +** benchmark. Here, an iteration consists of calculating the +** first n fourier coefficients of the function (x+1)^x on +** the interval 0,2. n is given by arraysize. +** NOTE: The # of integration steps is fixed at +** 200. +*/ +static ulong DoFPUTransIteration(fardouble *abase, /* A coeffs. */ + fardouble *bbase, /* B coeffs. */ + ulong arraysize) /* # of coeffs */ +{ +double omega; /* Fundamental frequency */ +unsigned long i; /* Index */ +unsigned long elapsed; /* Elapsed time */ + +/* +** Start the stopwatch +*/ +elapsed=StartStopwatch(); + +/* +** Calculate the fourier series. Begin by +** calculating A[0]. +*/ + +*abase=TrapezoidIntegrate((double)0.0, + (double)2.0, + 200, + (double)0.0, /* No omega * n needed */ + 0 )/(double)2.0; + +/* +** Calculate the fundamental frequency. +** ( 2 * pi ) / period...and since the period +** is 2, omega is simply pi. +*/ +omega=(double)3.1415926535897932; + +for(i=1;i +/* +#include +#include +#include +#include */ +#include "nmglobal.h" +#include "nbench1.h" + + +/***************************** +** FLOATING-POINT EMULATION ** +*****************************/ + +/************** +** DoEmFloat ** +*************** +** Perform the floating-point emulation routines portion of the +** CPU benchmark. Returns the operations per second. +*/ +void DoEmFloat(void) +{ +EmFloatStruct *locemfloatstruct; /* Local structure */ +InternalFPF *abase; /* Base of A array */ +InternalFPF *bbase; /* Base of B array */ +InternalFPF *cbase; /* Base of C array */ +unsigned long accumtime; /* Accumulated time in ticks */ +double iterations; /* # of iterations */ +unsigned long tickcount; /* # of ticks */ +char *errorcontext; /* Error context string pointer */ +int systemerror; /* For holding error code */ +unsigned long loops; /* # of loops */ + +/* +** Link to global structure +*/ +locemfloatstruct=&global_emfloatstruct; + +/* +** Set the error context +*/ +errorcontext="CPU:Floating Emulation"; + + +/* +** Test the emulation routines. +*/ +#ifdef DEBUG +#endif + +abase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF), + &systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + ErrorExit(); +} + +bbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF), + &systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + FreeMemory((void *)abase,&systemerror); + ErrorExit(); +} + +cbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF), + &systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + FreeMemory((void *)abase,&systemerror); + FreeMemory((void *)bbase,&systemerror); + ErrorExit(); +} + +/* +** Set up the arrays +*/ +SetupCPUEmFloatArrays(abase,bbase,cbase,locemfloatstruct->arraysize); + +/* +** See if we need to do self-adjusting code. +*/ +if(locemfloatstruct->adjust==0) +{ + locemfloatstruct->loops=0; + + /* + ** Do an iteration of the tests. If the elapsed time is + ** less than minimum, increase the loop count and try + ** again. + */ + for(loops=1;loopsarraysize, + loops); + if(tickcount>global_min_ticks) + { locemfloatstruct->loops=loops; + break; + } + } +} + +/* +** Verify that selft adjustment code worked. +*/ +if(locemfloatstruct->loops==0) +{ printf("CPU:EMFPU -- CMPUEMFLOATLOOPMAX limit hit\n"); + FreeMemory((void *)abase,&systemerror); + FreeMemory((void *)bbase,&systemerror); + FreeMemory((void *)cbase,&systemerror); + ErrorExit(); +} + +/* +** All's well if we get here. Repeatedly perform floating +** tests until the accumulated time is greater than the +** # of seconds requested. +** Each iteration performs arraysize * 3 operations. +*/ +accumtime=0L; +iterations=(double)0.0; +do { + accumtime+=DoEmFloatIteration(abase,bbase,cbase, + locemfloatstruct->arraysize, + locemfloatstruct->loops); + iterations+=(double)1.0; +} while(TicksToSecs(accumtime)request_secs); + + +/* +** Clean up, calculate results, and go home. +** Also, indicate that adjustment is done. +*/ +FreeMemory((void *)abase,&systemerror); +FreeMemory((void *)bbase,&systemerror); +FreeMemory((void *)cbase,&systemerror); + +locemfloatstruct->emflops=(iterations*(double)locemfloatstruct->loops)/ + (double)TicksToFracSecs(accumtime); +if(locemfloatstruct->adjust==0) + locemfloatstruct->adjust=1; + +#ifdef DEBUG +printf("----------------------------------------------------------------------------\n"); +#endif +return; +} diff --git a/huffman.c b/huffman.c new file mode 100644 index 0000000..961fc08 --- /dev/null +++ b/huffman.c @@ -0,0 +1,557 @@ +#include +#include +#include "nmglobal.h" +#include "nbench1.h" + +/* +** Word catalog +*/ +#define WORDCATSIZE 50 + +char *wordcatarray[WORDCATSIZE] = +{ "Hello", + "He", + "Him", + "the", + "this", + "that", + "though", + "rough", + "cough", + "obviously", + "But", + "but", + "bye", + "begin", + "beginning", + "beginnings", + "of", + "our", + "ourselves", + "yourselves", + "to", + "together", + "togetherness", + "from", + "either", + "I", + "A", + "return", + "However", + "that", + "example", + "yet", + "quickly", + "all", + "if", + "were", + "includes", + "always", + "never", + "not", + "small", + "returns", + "set", + "basic", + "Entered", + "with", + "used", + "shown", + "you", + "know" }; + + +/************************ +** HUFFMAN COMPRESSION ** +************************/ + +/************** +** DoHuffman ** +*************** +** Execute a huffman compression on a block of plaintext. +** Note that (as with IDEA encryption) an iteration of the +** Huffman test includes a compression AND a decompression. +** Also, the compression cycle includes building the +** Huffman tree. +*/ +void DoHuffman(void) +{ +HuffStruct *lochuffstruct; /* Loc pointer to global data */ +char *errorcontext; +int systemerror; +unsigned long accumtime; +double iterations; +char *comparray; +char *decomparray; +char *plaintext; + +/* +** Link to global data +*/ +lochuffstruct=&global_huffstruct; + +/* +** Set error context. +*/ +errorcontext="CPU:Huffman"; + +/* +** Allocate memory for the plaintext and the compressed text. +** We'll be really pessimistic here, and allocate equal amounts +** for both (though we know...well, we PRESUME) the compressed +** stuff will take less than the plain stuff. +** Also note that we'll build a 3rd buffer to decompress +** into, and we preallocate space for the huffman tree. +** (We presume that the Huffman tree will grow no larger +** than 512 bytes. This is actually a super-conservative +** estimate...but, who cares?) +*/ +plaintext=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); +} +comparray=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + FreeMemory(plaintext,&systemerror); +} +decomparray=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + FreeMemory(plaintext,&systemerror); + FreeMemory(comparray,&systemerror); +} + +hufftree=(huff_node *)AllocateMemory(sizeof(huff_node) * 512, + &systemerror); +if(systemerror) +{ ReportError(errorcontext,systemerror); + FreeMemory(plaintext,&systemerror); + FreeMemory(comparray,&systemerror); + FreeMemory(decomparray,&systemerror); +} + +/* +** Build the plaintext buffer. Since we want this to +** actually be able to compress, we'll use the +** wordcatalog to build the plaintext stuff. +*/ +/* +** Reset random number generator so things repeat. +** added by Uwe F. Mayer +*/ +randnum((int32_t)13); +create_text_block(plaintext,lochuffstruct->arraysize-1,(unsigned short)500); +plaintext[lochuffstruct->arraysize-1L]='\0'; +plaintextlen=lochuffstruct->arraysize; + +/* +** See if we need to perform self adjustment loop. +*/ +if(lochuffstruct->adjust==0) +{ + /* + ** Do self-adjustment. This involves initializing the + ** # of loops and increasing the loop count until we + ** get a number of loops that we can use. + */ + for(lochuffstruct->loops=100L; + lochuffstruct->loopsloops+=10L) + if(DoHuffIteration(plaintext, + comparray, + decomparray, + lochuffstruct->arraysize, + lochuffstruct->loops, + hufftree)>global_min_ticks) break; +} + +/* +** All's well if we get here. Do the test. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoHuffIteration(plaintext, + comparray, + decomparray, + lochuffstruct->arraysize, + lochuffstruct->loops, + hufftree); + iterations+=(double)lochuffstruct->loops; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +FreeMemory((void *)plaintext,&systemerror); +FreeMemory((void *)comparray,&systemerror); +FreeMemory((void *)decomparray,&systemerror); +FreeMemory((void *)hufftree,&systemerror); +lochuffstruct->iterspersec=iterations / TicksToFracSecs(accumtime); + +if(lochuffstruct->adjust==0) + lochuffstruct->adjust=1; + +} + +/********************* +** create_text_line ** +********************** +** Create a random line of text, stored at *dt. The line may be +** no more than nchars long. +*/ +static void create_text_line(char *dt, + long nchars) +{ +long charssofar; /* # of characters so far */ +long tomove; /* # of characters to move */ +char myword[40]; /* Local buffer for words */ +char *wordptr; /* Pointer to word from catalog */ + +charssofar=0; + +do { +/* +** Grab a random word from the wordcatalog +*/ +/* wordptr=wordcatarray[abs_randwc((long)WORDCATSIZE)];*/ +wordptr=wordcatarray[abs_randwc((int32_t)WORDCATSIZE)]; +MoveMemory((void *)myword, + (void *)wordptr, + (unsigned long)strlen(wordptr)+1); + +/* +** Append a blank. +*/ +tomove=strlen(myword)+1; +myword[tomove-1]=' '; + +/* +** See how long it is. If its length+charssofar > nchars, we have +** to trim it. +*/ +if((tomove+charssofar)>nchars) + tomove=nchars-charssofar; +/* +** Attach the word to the current line. Increment counter. +*/ +MoveMemory((void *)dt,(void *)myword,(unsigned long)tomove); +charssofar+=tomove; +dt+=tomove; + +/* +** If we're done, bail out. Otherwise, go get another word. +*/ +} while(charssofartblen) + linelen=tblen-bytessofar; + +if(linelen>1) +{ + create_text_line(tb,linelen); +} +tb+=linelen-1; /* Add the carriage return */ +*tb++='\n'; + +bytessofar+=linelen; + +} while(bytessofar>3; +bitnumb=bitoffset % 8; + +/* +** Set or clear +*/ +if(bitchar=='1') + comparray[byteoffset]|=(1<>3; +bitnumb=bitoffset % 8; + +/* +** Fetch +*/ +return((1<>encrypt>> crypt1 >>decrypt>> plain2. +** So, plain1 and plain2 should match. +** Also, fill up plain1 with sample text. +*/ +plain1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); +if(systemerror) +{ + ReportError(errorcontext,systemerror); + ErrorExit(); +} + +crypt1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); +if(systemerror) +{ + ReportError(errorcontext,systemerror); + FreeMemory((farvoid *)plain1,&systemerror); + ErrorExit(); +} + +plain2=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); +if(systemerror) +{ + ReportError(errorcontext,systemerror); + FreeMemory((farvoid *)plain1,&systemerror); + FreeMemory((farvoid *)crypt1,&systemerror); + ErrorExit(); +} +/* +** Note that we build the "plaintext" by simply loading +** the array up with random numbers. +*/ +for(i=0;iarraysize;i++) + plain1[i]=(uchar)(abs_randwc(255) & 0xFF); + +/* +** See if we need to perform self adjustment loop. +*/ +if(locideastruct->adjust==0) +{ + /* + ** Do self-adjustment. This involves initializing the + ** # of loops and increasing the loop count until we + ** get a number of loops that we can use. + */ + for(locideastruct->loops=100L; + locideastruct->loopsloops+=10L) + if(DoIDEAIteration(plain1,crypt1,plain2, + locideastruct->arraysize, + locideastruct->loops, + Z,DK)>global_min_ticks) break; +} + +/* +** All's well if we get here. Do the test. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoIDEAIteration(plain1,crypt1,plain2, + locideastruct->arraysize, + locideastruct->loops,Z,DK); + iterations+=(double)locideastruct->loops; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +FreeMemory((farvoid *)plain1,&systemerror); +FreeMemory((farvoid *)crypt1,&systemerror); +FreeMemory((farvoid *)plain2,&systemerror); +locideastruct->iterspersec=iterations / TicksToFracSecs(accumtime); + +if(locideastruct->adjust==0) + locideastruct->adjust=1; + +return; + +} + +/******************** +** DoIDEAIteration ** +********************* +** Execute a single iteration of the IDEA encryption algorithm. +** Actually, a single iteration is one encryption and one +** decryption. +*/ +static ulong DoIDEAIteration(faruchar *plain1, + faruchar *crypt1, + faruchar *plain2, + ulong arraysize, + ulong nloops, + IDEAkey Z, + IDEAkey DK) +{ +register ulong i; +register ulong j; +ulong elapsed; +#ifdef DEBUG +int status=0; +#endif + +/* +** Start the stopwatch. +*/ +elapsed=StartStopwatch(); + +/* +** Do everything for nloops. +*/ +for(i=0;i>16); + return(b-a+(b> 7); + Z+=i&8; + i&=7; +} +return; +} + +/**************** +** de_key_idea ** +***************** +** Compute IDEA decryption subkeys DK from encryption +** subkeys Z. +*/ +static void de_key_idea(IDEAkey Z, IDEAkey DK) +{ +IDEAkey TT; +int j; +u16 t1, t2, t3; +u16 *p; +p=(u16 *)(TT+KEYLEN); + +t1=inv(*Z++); +t2=-*Z++; +t3=-*Z++; +*--p=inv(*Z++); +*--p=t3; +*--p=t2; +*--p=t1; + +for(j=1;j +/*#include +#include +#include */ +#include +#include +#include "nmglobal.h" +#include "nbench1.h" + +/*********************** +** LU DECOMPOSITION ** +** (Linear Equations) ** +************************ +** These routines come from "Numerical Recipes in Pascal". +** Note that, as in the assignment algorithm, though we +** separately define LUARRAYROWS and LUARRAYCOLS, the two +** must be the same value (this routine depends on a square +** matrix). +*/ + +/********* +** DoLU ** +********** +** Perform the LU decomposition benchmark. +*/ +void DoLU(void) +{ +LUStruct *loclustruct; /* Local pointer to global data */ +char *errorcontext; +int systemerror; +fardouble *a; +fardouble *b; +fardouble *abase; +fardouble *bbase; +LUdblptr ptra; +int n; +int i; +ulong accumtime; +double iterations; + +/* +** Link to global data +*/ +loclustruct=&global_lustruct; + +/* +** Set error context. +*/ +errorcontext="FPU:LU"; + +/* +** Our first step is to build a "solvable" problem. This +** will become the "seed" set that all others will be +** derived from. (I.E., we'll simply copy these arrays +** into the others. +*/ +a=(fardouble *)AllocateMemory(sizeof(double) * LUARRAYCOLS * LUARRAYROWS, + &systemerror); +b=(fardouble *)AllocateMemory(sizeof(double) * LUARRAYROWS, + &systemerror); +n=LUARRAYROWS; + +/* +** We need to allocate a temp vector that is used by the LU +** algorithm. This removes the allocation routine from the +** timing. +*/ +LUtempvv=(fardouble *)AllocateMemory(sizeof(double)*LUARRAYROWS, + &systemerror); + +/* +** Build a problem to be solved. +*/ +ptra.ptrs.p=a; /* Gotta coerce linear array to 2D array */ +build_problem(*ptra.ptrs.ap,n,b); + +/* +** Now that we have a problem built, see if we need to do +** auto-adjust. If so, repeatedly call the DoLUIteration routine, +** increasing the number of solutions per iteration as you go. +*/ +if(loclustruct->adjust==0) +{ + loclustruct->numarrays=0; + for(i=1;i<=MAXLUARRAYS;i++) + { + abase=(fardouble *)AllocateMemory(sizeof(double) * + LUARRAYCOLS*LUARRAYROWS*(i+1),&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + LUFreeMem(a,b,(fardouble *)NULL,(fardouble *)NULL); + ErrorExit(); + } + bbase=(fardouble *)AllocateMemory(sizeof(double) * + LUARRAYROWS*(i+1),&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + LUFreeMem(a,b,abase,(fardouble *)NULL); + ErrorExit(); + } + if(DoLUIteration(a,b,abase,bbase,i)>global_min_ticks) + { loclustruct->numarrays=i; + break; + } + /* + ** Not enough arrays...free them all and try again + */ + FreeMemory((farvoid *)abase,&systemerror); + FreeMemory((farvoid *)bbase,&systemerror); + } + /* + ** Were we able to do it? + */ + if(loclustruct->numarrays==0) + { printf("FPU:LU -- Array limit reached\n"); + LUFreeMem(a,b,abase,bbase); + ErrorExit(); + } +} +else +{ /* + ** Don't need to adjust -- just allocate the proper + ** number of arrays and proceed. + */ + abase=(fardouble *)AllocateMemory(sizeof(double) * + LUARRAYCOLS*LUARRAYROWS*loclustruct->numarrays, + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + LUFreeMem(a,b,(fardouble *)NULL,(fardouble *)NULL); + ErrorExit(); + } + bbase=(fardouble *)AllocateMemory(sizeof(double) * + LUARRAYROWS*loclustruct->numarrays,&systemerror); + if(systemerror) + { + ReportError(errorcontext,systemerror); + LUFreeMem(a,b,abase,(fardouble *)NULL); + ErrorExit(); + } +} +/* +** All's well if we get here. Do the test. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoLUIteration(a,b,abase,bbase, + loclustruct->numarrays); + iterations+=(double)loclustruct->numarrays; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +loclustruct->iterspersec=iterations / TicksToFracSecs(accumtime); + +if(loclustruct->adjust==0) + loclustruct->adjust=1; + +LUFreeMem(a,b,abase,bbase); +return; +} + +/************** +** LUFreeMem ** +*************** +** Release memory associated with LU benchmark. +*/ +static void LUFreeMem(fardouble *a, fardouble *b, + fardouble *abase,fardouble *bbase) +{ +int systemerror; + +FreeMemory((farvoid *)a,&systemerror); +FreeMemory((farvoid *)b,&systemerror); +FreeMemory((farvoid *)LUtempvv,&systemerror); + +if(abase!=(fardouble *)NULL) FreeMemory((farvoid *)abase,&systemerror); +if(bbase!=(fardouble *)NULL) FreeMemory((farvoid *)bbase,&systemerror); +return; +} + +/****************** +** DoLUIteration ** +******************* +** Perform an iteration of the LU decomposition benchmark. +** An iteration refers to the repeated solution of several +** identical matrices. +*/ +static ulong DoLUIteration(fardouble *a,fardouble *b, + fardouble *abase, fardouble *bbase, + ulong numarrays) +{ +fardouble *locabase; +fardouble *locbbase; +LUdblptr ptra; /* For converting ptr to 2D array */ +ulong elapsed; +ulong j,i; /* Indexes */ + + +/* +** Move the seed arrays (a & b) into the destination +** arrays; +*/ +for(j=0;j big) + big=fabs(a[i][j]); + /* Bail out on singular matrix */ + if(big==(double)0.0) return(0); + LUtempvv[i]=1.0/big; +} + +/* +** Crout's algorithm...loop over columns. +*/ +for(j=0;j=big) + { big=dum; + imax=i; + } + } + if(j!=imax) /* Interchange rows if necessary */ + { for(k=0;k=0;i--) +{ + sum=b[i]; + if(i!=(n-1)) + for(j=(i+1);j -#include -#include -#include -#include -#include "nmglobal.h" -#include "nbench1.h" -#include "wordcat.h" - -#ifdef DEBUG -static int numsort_status=0; -static int stringsort_status=0; -#endif - -/********************* -** NUMERIC HEAPSORT ** -********************** -** This test implements a heapsort algorithm, performed on an -** array of longs. -*/ - -/************** -** DoNumSort ** -*************** -** This routine performs the CPU numeric sort test. -** NOTE: Last version incorrectly stated that the routine -** returned result in # of longword sorted per second. -** Not so; the routine returns # of iterations per sec. -*/ - -void DoNumSort(void) -{ -SortStruct *numsortstruct; /* Local pointer to global struct */ -farlong *arraybase; /* Base pointers of array */ -long accumtime; /* Accumulated time */ -double iterations; /* Iteration counter */ -char *errorcontext; /* Error context string pointer */ -int systemerror; /* For holding error codes */ - -/* -** Link to global structure -*/ -numsortstruct=&global_numsortstruct; - -/* -** Set the error context string. -*/ -errorcontext="CPU:Numeric Sort"; - -/* -** See if we need to do self adjustment code. -*/ -if(numsortstruct->adjust==0) -{ - /* - ** Self-adjustment code. The system begins by sorting 1 - ** array. If it does that in no time, then two arrays - ** are built and sorted. This process continues until - ** enough arrays are built to handle the tolerance. - */ - numsortstruct->numarrays=1; - while(1) - { - /* - ** Allocate space for arrays - */ - arraybase=(farlong *)AllocateMemory(sizeof(long) * - numsortstruct->numarrays * numsortstruct->arraysize, - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)arraybase, - &systemerror); - ErrorExit(); - } - - /* - ** Do an iteration of the numeric sort. If the - ** elapsed time is less than or equal to the permitted - ** minimum, then allocate for more arrays and - ** try again. - */ - if(DoNumSortIteration(arraybase, - numsortstruct->arraysize, - numsortstruct->numarrays)>global_min_ticks) - break; /* We're ok...exit */ - - FreeMemory((farvoid *)arraybase,&systemerror); - if(numsortstruct->numarrays++>NUMNUMARRAYS) - { printf("CPU:NSORT -- NUMNUMARRAYS hit.\n"); - ErrorExit(); - } - } -} -else -{ /* - ** Allocate space for arrays - */ - arraybase=(farlong *)AllocateMemory(sizeof(long) * - numsortstruct->numarrays * numsortstruct->arraysize, - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)arraybase, - &systemerror); - ErrorExit(); - } - -} -/* -** All's well if we get here. Repeatedly perform sorts until the -** accumulated elapsed time is greater than # of seconds requested. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoNumSortIteration(arraybase, - numsortstruct->arraysize, - numsortstruct->numarrays); - iterations+=(double)1.0; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -FreeMemory((farvoid *)arraybase,&systemerror); - -numsortstruct->sortspersec=iterations * - (double)numsortstruct->numarrays / TicksToFracSecs(accumtime); - -if(numsortstruct->adjust==0) - numsortstruct->adjust=1; - -#ifdef DEBUG -if (numsort_status==0) printf("Numeric sort: OK\n"); -numsort_status=0; -#endif -return; -} - -/*********************** -** DoNumSortIteration ** -************************ -** This routine executes one iteration of the numeric -** sort benchmark. It returns the number of ticks -** elapsed for the iteration. -*/ -static ulong DoNumSortIteration(farlong *arraybase, - ulong arraysize, - uint numarrays) -{ -ulong elapsed; /* Elapsed ticks */ -ulong i; -/* -** Load up the array with random numbers -*/ -LoadNumArrayWithRand(arraybase,arraysize,numarrays); - -/* -** Start the stopwatch -*/ -elapsed=StartStopwatch(); - -/* -** Execute a heap of heapsorts -*/ -for(i=0;i0; --i) - NumSift(array,i,top); - -/* -** Repeatedly extract maximum from heap and place it at the -** end of the array. When we get done, we'll have a sorted -** array. -*/ -for(i=top; i>0; --i) -{ NumSift(array,bottom,i); - temp=*array; /* Perform exchange */ - *array=*(array+i); - *(array+i)=temp; -} -return; -} - -/************ -** NumSift ** -************* -** Peforms the sift operation on a numeric array, -** constructing a heap in the array. -*/ -static void NumSift(farlong *array, /* Array of numbers */ - ulong i, /* Minimum of array */ - ulong j) /* Maximum of array */ -{ -unsigned long k; -long temp; /* Used for exchange */ - -while((i+i)<=j) -{ - k=i+i; - if(kadjust==0) -{ - /* - ** Initialize the number of arrays. - */ - strsortstruct->numarrays=1; - while(1) - { - /* - ** Allocate space for array. We'll add an extra 100 - ** bytes to protect memory as strings move around - ** (this can happen during string adjustment) - */ - arraybase=(faruchar *)AllocateMemory((strsortstruct->arraysize+100L) * - (long)strsortstruct->numarrays,&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } - - /* - ** Do an iteration of the string sort. If the - ** elapsed time is less than or equal to the permitted - ** minimum, then de-allocate the array, reallocate a - ** an additional array, and try again. - */ - if(DoStringSortIteration(arraybase, - strsortstruct->numarrays, - strsortstruct->arraysize)>global_min_ticks) - break; /* We're ok...exit */ - - FreeMemory((farvoid *)arraybase,&systemerror); - strsortstruct->numarrays+=1; - } -} -else -{ - /* - ** We don't have to perform self adjustment code. - ** Simply allocate the space for the array. - */ - arraybase=(faruchar *)AllocateMemory((strsortstruct->arraysize+100L) * - (long)strsortstruct->numarrays,&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } -} -/* -** All's well if we get here. Repeatedly perform sorts until the -** accumulated elapsed time is greater than # of seconds requested. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoStringSortIteration(arraybase, - strsortstruct->numarrays, - strsortstruct->arraysize); - iterations+=(double)strsortstruct->numarrays; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. -** Set flag to show we don't need to rerun adjustment code. -*/ -FreeMemory((farvoid *)arraybase,&systemerror); -strsortstruct->sortspersec=iterations / (double)TicksToFracSecs(accumtime); -if(strsortstruct->adjust==0) - strsortstruct->adjust=1; -#ifdef DEBUG -if (stringsort_status==0) printf("String sort: OK\n"); -stringsort_status=0; -#endif -return; -} - -/************************** -** DoStringSortIteration ** -*************************** -** This routine executes one iteration of the string -** sort benchmark. It returns the number of ticks -** Note that this routine also builds the offset pointer -** array. -*/ -static ulong DoStringSortIteration(faruchar *arraybase, - uint numarrays,ulong arraysize) -{ -farulong *optrarray; /* Offset pointer array */ -unsigned long elapsed; /* Elapsed ticks */ -unsigned long nstrings; /* # of strings in array */ -int syserror; /* System error code */ -unsigned int i; /* Index */ -farulong *tempobase; /* Temporary offset pointer base */ -faruchar *tempsbase; /* Temporary string base pointer */ - -/* -** Load up the array(s) with random numbers -*/ -optrarray=LoadStringArray(arraybase,numarrays,&nstrings,arraysize); - -/* -** Set temp base pointers...they will be modified as the -** benchmark proceeds. -*/ -tempobase=optrarray; -tempsbase=arraybase; - -/* -** Start the stopwatch -*/ -elapsed=StartStopwatch(); - -/* -** Execute heapsorts -*/ -for(i=0;i=arraysize) - { stringlength=(unsigned char)((arraysize-curroffset-1L) & - 0xFF); - fullflag=1; /* Indicates a full */ - } - - /* - ** Store length at curroffset and advance current offset. - */ - *(strarray+curroffset)=stringlength; - curroffset++; - - /* - ** Fill up the rest of the string with random bytes. - */ - for(i=0;i0; --i) - strsift(optrarray,strarray,numstrings,i,top); - -/* -** Repeatedly extract maximum from heap and place it at the -** end of the array. When we get done, we'll have a sorted -** array. -*/ -for(i=top; i>0; --i) -{ - strsift(optrarray,strarray,numstrings,0,i); - - /* temp = string[0] */ - tlen=*strarray; - MoveMemory((farvoid *)&temp[0], /* Perform exchange */ - (farvoid *)strarray, - (unsigned long)(tlen+1)); - - - /* string[0]=string[i] */ - tlen=*(strarray+*(optrarray+i)); - stradjust(optrarray,strarray,numstrings,0,tlen); - MoveMemory((farvoid *)strarray, - (farvoid *)(strarray+*(optrarray+i)), - (unsigned long)(tlen+1)); - - /* string[i]=temp */ - tlen=temp[0]; - stradjust(optrarray,strarray,numstrings,i,tlen); - MoveMemory((farvoid *)(strarray+*(optrarray+i)), - (farvoid *)&temp[0], - (unsigned long)(tlen+1)); - -} -return; -} - -/**************** -** str_is_less ** -***************** -** Pass this function: -** 1) A pointer to an array of offset pointers -** 2) A pointer to a string array -** 3) The number of elements in the string array -** 4) Offsets to two strings (a & b) -** This function returns TRUE if string a is < string b. -*/ -static int str_is_less(farulong *optrarray, /* Offset pointers */ - faruchar *strarray, /* String array */ - ulong numstrings, /* # of strings */ - ulong a, ulong b) /* Offsets */ -{ -int slen; /* String length */ - -/* -** Determine which string has the minimum length. Use that -** to call strncmp(). If they match up to that point, the -** string with the longer length wins. -*/ -slen=(int)*(strarray+*(optrarray+a)); -if(slen > (int)*(strarray+*(optrarray+b))) - slen=(int)*(strarray+*(optrarray+b)); - -slen=strncmp((char *)(strarray+*(optrarray+a)), - (char *)(strarray+*(optrarray+b)),slen); - -if(slen==0) -{ - /* - ** They match. Return true if the length of a - ** is greater than the length of b. - */ - if(*(strarray+*(optrarray+a)) > - *(strarray+*(optrarray+b))) - return(TRUE); - return(FALSE); -} - -if(slen<0) return(TRUE); /* a is strictly less than b */ - -return(FALSE); /* Only other possibility */ -} - -/************ -** strsift ** -************* -** Pass this function: -** 1) A pointer to an array of offset pointers -** 2) A pointer to a string array -** 3) The number of elements in the string array -** 4) Offset within which to sort. -** Sift the array within the bounds of those offsets (thus -** building a heap). -*/ -static void strsift(farulong *optrarray, /* Offset pointers */ - faruchar *strarray, /* String array */ - ulong numstrings, /* # of strings */ - ulong i, ulong j) /* Offsets */ -{ -unsigned long k; /* Temporaries */ -unsigned char temp[80]; -unsigned char tlen; /* For string lengths */ - - -while((i+i)<=j) -{ - k=i+i; - if(kadjust==0) -{ - bitarraybase=(farulong *)AllocateMemory(locbitopstruct->bitfieldarraysize * - sizeof(ulong),&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } - - /* - ** Initialize bitfield operations array to [2,30] elements - */ - locbitopstruct->bitoparraysize=30L; - - while(1) - { - /* - ** Allocate space for operations array - */ - bitoparraybase=(farulong *)AllocateMemory(locbitopstruct->bitoparraysize*2L* - sizeof(ulong), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)bitarraybase,&systemerror); - ErrorExit(); - } - /* - ** Do an iteration of the bitmap test. If the - ** elapsed time is less than or equal to the permitted - ** minimum, then de-allocate the array, reallocate a - ** larger version, and try again. - */ - ticks=DoBitfieldIteration(bitarraybase, - bitoparraybase, - locbitopstruct->bitoparraysize, - &nbitops); -#ifdef DEBUG -#ifdef LINUX - if (locbitopstruct->bitoparraysize==30L){ - /* this is the first loop, write a debug file */ - FILE *file; - unsigned long *running_base; /* same as farulong */ - long counter; - file=fopen("debugbit.dat","w"); - running_base=bitarraybase; - for (counter=0;counter<(long)(locbitopstruct->bitfieldarraysize);counter++){ -#ifdef LONG64 - fprintf(file,"%08X",(unsigned int)(*running_base&0xFFFFFFFFL)); - fprintf(file,"%08X",(unsigned int)((*running_base>>32)&0xFFFFFFFFL)); - if ((counter+1)%4==0) fprintf(file,"\n"); -#else - fprintf(file,"%08lX",*running_base); - if ((counter+1)%8==0) fprintf(file,"\n"); -#endif - running_base=running_base+1; - } - fclose(file); - printf("\nWrote the file debugbit.dat, you may want to compare it to debugbit.good\n"); - } -#endif -#endif - - if (ticks>global_min_ticks) break; /* We're ok...exit */ - - FreeMemory((farvoid *)bitoparraybase,&systemerror); - locbitopstruct->bitoparraysize+=100L; - } -} -else -{ - /* - ** Don't need to do self adjustment, just allocate - ** the array space. - */ - bitarraybase=(farulong *)AllocateMemory(locbitopstruct->bitfieldarraysize * - sizeof(ulong),&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } - bitoparraybase=(farulong *)AllocateMemory(locbitopstruct->bitoparraysize*2L* - sizeof(ulong), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)bitarraybase,&systemerror); - ErrorExit(); - } -} - -/* -** All's well if we get here. Repeatedly perform bitops until the -** accumulated elapsed time is greater than # of seconds requested. -*/ -accumtime=0L; -iterations=(double)0.0; -do { - accumtime+=DoBitfieldIteration(bitarraybase, - bitoparraybase, - locbitopstruct->bitoparraysize,&nbitops); - iterations+=(double)nbitops; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. -** Also, set adjustment flag to show that we don't have -** to do self adjusting in the future. -*/ -FreeMemory((farvoid *)bitarraybase,&systemerror); -FreeMemory((farvoid *)bitoparraybase,&systemerror); -locbitopstruct->bitopspersec=iterations /TicksToFracSecs(accumtime); -if(locbitopstruct->adjust==0) - locbitopstruct->adjust=1; - -return; -} - -/************************ -** DoBitfieldIteration ** -************************* -** Perform a single iteration of the bitfield benchmark. -** Return the # of ticks accumulated by the operation. -*/ -static ulong DoBitfieldIteration(farulong *bitarraybase, - farulong *bitoparraybase, - long bitoparraysize, - ulong *nbitops) -{ -long i; /* Index */ -ulong bitoffset; /* Offset into bitmap */ -ulong elapsed; /* Time to execute */ -/* -** Clear # bitops counter -*/ -*nbitops=0L; - -/* -** Construct a set of bitmap offsets and run lengths. -** The offset can be any random number from 0 to the -** size of the bitmap (in bits). The run length can -** be any random number from 1 to the number of bits -** between the offset and the end of the bitmap. -** Note that the bitmap has 8192 * 32 bits in it. -** (262,144 bits) -*/ -/* -** Reset random number generator so things repeat. -** Also reset the bit array we work on. -** added by Uwe F. Mayer -*/ -randnum((int32)13); -for (i=0;i>6; /* Index is number /64 */ - bitnumb=bit_addr % 64; /* Bit number in word */ -#else - bindex=bit_addr>>5; /* Index is number /32 */ - bitnumb=bit_addr % 32; /* bit number in word */ -#endif - if(val) - bitmap[bindex]|=(1L<>6; /* Index is number /64 */ - bitnumb=bit_addr % 64; /* Bit number in longword */ -#else - bindex=bit_addr>>5; /* Index is number /32 */ - bitnumb=bit_addr % 32; /* Bit number in longword */ -#endif - bitmap[bindex]^=(1L<arraysize*sizeof(InternalFPF), - &systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - ErrorExit(); -} - -bbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF), - &systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)abase,&systemerror); - ErrorExit(); -} - -cbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF), - &systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)abase,&systemerror); - FreeMemory((farvoid *)bbase,&systemerror); - ErrorExit(); -} - -/* -** Set up the arrays -*/ -SetupCPUEmFloatArrays(abase,bbase,cbase,locemfloatstruct->arraysize); - -/* -** See if we need to do self-adjusting code. -*/ -if(locemfloatstruct->adjust==0) -{ - locemfloatstruct->loops=0; - - /* - ** Do an iteration of the tests. If the elapsed time is - ** less than minimum, increase the loop count and try - ** again. - */ - for(loops=1;loopsarraysize, - loops); - if(tickcount>global_min_ticks) - { locemfloatstruct->loops=loops; - break; - } - } -} - -/* -** Verify that selft adjustment code worked. -*/ -if(locemfloatstruct->loops==0) -{ printf("CPU:EMFPU -- CMPUEMFLOATLOOPMAX limit hit\n"); - FreeMemory((farvoid *)abase,&systemerror); - FreeMemory((farvoid *)bbase,&systemerror); - FreeMemory((farvoid *)cbase,&systemerror); - ErrorExit(); -} - -/* -** All's well if we get here. Repeatedly perform floating -** tests until the accumulated time is greater than the -** # of seconds requested. -** Each iteration performs arraysize * 3 operations. -*/ -accumtime=0L; -iterations=(double)0.0; -do { - accumtime+=DoEmFloatIteration(abase,bbase,cbase, - locemfloatstruct->arraysize, - locemfloatstruct->loops); - iterations+=(double)1.0; -} while(TicksToSecs(accumtime)request_secs); - - -/* -** Clean up, calculate results, and go home. -** Also, indicate that adjustment is done. -*/ -FreeMemory((farvoid *)abase,&systemerror); -FreeMemory((farvoid *)bbase,&systemerror); -FreeMemory((farvoid *)cbase,&systemerror); - -locemfloatstruct->emflops=(iterations*(double)locemfloatstruct->loops)/ - (double)TicksToFracSecs(accumtime); -if(locemfloatstruct->adjust==0) - locemfloatstruct->adjust=1; - -#ifdef DEBUG -printf("----------------------------------------------------------------------------\n"); -#endif -return; -} - -/************************* -** FOURIER COEFFICIENTS ** -*************************/ - -/************** -** DoFourier ** -*************** -** Perform the transcendental/trigonometric portion of the -** benchmark. This benchmark calculates the first n -** fourier coefficients of the function (x+1)^x defined -** on the interval 0,2. -*/ -void DoFourier(void) -{ -FourierStruct *locfourierstruct; /* Local fourier struct */ -fardouble *abase; /* Base of A[] coefficients array */ -fardouble *bbase; /* Base of B[] coefficients array */ -unsigned long accumtime; /* Accumulated time in ticks */ -double iterations; /* # of iterations */ -char *errorcontext; /* Error context string pointer */ -int systemerror; /* For error code */ - -/* -** Link to global structure -*/ -locfourierstruct=&global_fourierstruct; - -/* -** Set error context string -*/ -errorcontext="FPU:Transcendental"; - -/* -** See if we need to do self-adjustment code. -*/ -if(locfourierstruct->adjust==0) -{ - locfourierstruct->arraysize=100L; /* Start at 100 elements */ - while(1) - { - - abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } - - bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((void *)abase,&systemerror); - ErrorExit(); - } - /* - ** Do an iteration of the tests. If the elapsed time is - ** less than or equal to the permitted minimum, re-allocate - ** larger arrays and try again. - */ - if(DoFPUTransIteration(abase,bbase, - locfourierstruct->arraysize)>global_min_ticks) - break; /* We're ok...exit */ - - /* - ** Make bigger arrays and try again. - */ - FreeMemory((farvoid *)abase,&systemerror); - FreeMemory((farvoid *)bbase,&systemerror); - locfourierstruct->arraysize+=50L; - } -} -else -{ /* - ** Don't need self-adjustment. Just allocate the - ** arrays, and go. - */ - abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - ErrorExit(); - } - - bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((void *)abase,&systemerror); - ErrorExit(); - } -} -/* -** All's well if we get here. Repeatedly perform integration -** tests until the accumulated time is greater than the -** # of seconds requested. -*/ -accumtime=0L; -iterations=(double)0.0; -do { - accumtime+=DoFPUTransIteration(abase,bbase,locfourierstruct->arraysize); - iterations+=(double)locfourierstruct->arraysize*(double)2.0-(double)1.0; -} while(TicksToSecs(accumtime)request_secs); - - -/* -** Clean up, calculate results, and go home. -** Also set adjustment flag to indicate no adjust code needed. -*/ -FreeMemory((farvoid *)abase,&systemerror); -FreeMemory((farvoid *)bbase,&systemerror); - -locfourierstruct->fflops=iterations/(double)TicksToFracSecs(accumtime); - -if(locfourierstruct->adjust==0) - locfourierstruct->adjust=1; - -return; -} - -/************************ -** DoFPUTransIteration ** -************************* -** Perform an iteration of the FPU Transcendental/trigonometric -** benchmark. Here, an iteration consists of calculating the -** first n fourier coefficients of the function (x+1)^x on -** the interval 0,2. n is given by arraysize. -** NOTE: The # of integration steps is fixed at -** 200. -*/ -static ulong DoFPUTransIteration(fardouble *abase, /* A coeffs. */ - fardouble *bbase, /* B coeffs. */ - ulong arraysize) /* # of coeffs */ -{ -double omega; /* Fundamental frequency */ -unsigned long i; /* Index */ -unsigned long elapsed; /* Elapsed time */ - -/* -** Start the stopwatch -*/ -elapsed=StartStopwatch(); - -/* -** Calculate the fourier series. Begin by -** calculating A[0]. -*/ - -*abase=TrapezoidIntegrate((double)0.0, - (double)2.0, - 200, - (double)0.0, /* No omega * n needed */ - 0 )/(double)2.0; - -/* -** Calculate the fundamental frequency. -** ( 2 * pi ) / period...and since the period -** is 2, omega is simply pi. -*/ -omega=(double)3.1415926535897932; - -for(i=1;iadjust==0) -{ - /* - ** Self-adjustment code. The system begins by working on 1 - ** array. If it does that in no time, then two arrays - ** are built. This process continues until - ** enough arrays are built to handle the tolerance. - */ - locassignstruct->numarrays=1; - while(1) - { - /* - ** Allocate space for arrays - */ - arraybase=(farlong *) AllocateMemory(sizeof(long)* - ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays, - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)arraybase, - &systemerror); - ErrorExit(); - } - - /* - ** Do an iteration of the assignment alg. If the - ** elapsed time is less than or equal to the permitted - ** minimum, then allocate for more arrays and - ** try again. - */ - if(DoAssignIteration(arraybase, - locassignstruct->numarrays)>global_min_ticks) - break; /* We're ok...exit */ - - FreeMemory((farvoid *)arraybase, &systemerror); - locassignstruct->numarrays++; - } -} -else -{ /* - ** Allocate space for arrays - */ - arraybase=(farlong *)AllocateMemory(sizeof(long)* - ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays, - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)arraybase, - &systemerror); - ErrorExit(); - } -} - -/* -** All's well if we get here. Do the tests. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoAssignIteration(arraybase, - locassignstruct->numarrays); - iterations+=(double)1.0; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -FreeMemory((farvoid *)arraybase,&systemerror); - -locassignstruct->iterspersec=iterations * - (double)locassignstruct->numarrays / TicksToFracSecs(accumtime); - -if(locassignstruct->adjust==0) - locassignstruct->adjust=1; - -return; - -} - -/********************** -** DoAssignIteration ** -*********************** -** This routine executes one iteration of the assignment test. -** It returns the number of ticks elapsed in the iteration. -*/ -static ulong DoAssignIteration(farlong *arraybase, - ulong numarrays) -{ -longptr abase; /* local pointer */ -ulong elapsed; /* Elapsed ticks */ -ulong i; - -/* -** Set up local pointer -*/ -abase.ptrs.p=arraybase; - -/* -** Load up the arrays with a random table. -*/ -LoadAssignArrayWithRand(arraybase,numarrays); - -/* -** Start the stopwatch -*/ -elapsed=StartStopwatch(); - -/* -** Execute assignment algorithms -*/ -for(i=0;i1) - for(i=1;i>encrypt>> crypt1 >>decrypt>> plain2. -** So, plain1 and plain2 should match. -** Also, fill up plain1 with sample text. -*/ -plain1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); -if(systemerror) -{ - ReportError(errorcontext,systemerror); - ErrorExit(); -} - -crypt1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); -if(systemerror) -{ - ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)plain1,&systemerror); - ErrorExit(); -} - -plain2=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror); -if(systemerror) -{ - ReportError(errorcontext,systemerror); - FreeMemory((farvoid *)plain1,&systemerror); - FreeMemory((farvoid *)crypt1,&systemerror); - ErrorExit(); -} -/* -** Note that we build the "plaintext" by simply loading -** the array up with random numbers. -*/ -for(i=0;iarraysize;i++) - plain1[i]=(uchar)(abs_randwc(255) & 0xFF); - -/* -** See if we need to perform self adjustment loop. -*/ -if(locideastruct->adjust==0) -{ - /* - ** Do self-adjustment. This involves initializing the - ** # of loops and increasing the loop count until we - ** get a number of loops that we can use. - */ - for(locideastruct->loops=100L; - locideastruct->loopsloops+=10L) - if(DoIDEAIteration(plain1,crypt1,plain2, - locideastruct->arraysize, - locideastruct->loops, - Z,DK)>global_min_ticks) break; -} - -/* -** All's well if we get here. Do the test. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoIDEAIteration(plain1,crypt1,plain2, - locideastruct->arraysize, - locideastruct->loops,Z,DK); - iterations+=(double)locideastruct->loops; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -FreeMemory((farvoid *)plain1,&systemerror); -FreeMemory((farvoid *)crypt1,&systemerror); -FreeMemory((farvoid *)plain2,&systemerror); -locideastruct->iterspersec=iterations / TicksToFracSecs(accumtime); - -if(locideastruct->adjust==0) - locideastruct->adjust=1; - -return; - -} - -/******************** -** DoIDEAIteration ** -********************* -** Execute a single iteration of the IDEA encryption algorithm. -** Actually, a single iteration is one encryption and one -** decryption. -*/ -static ulong DoIDEAIteration(faruchar *plain1, - faruchar *crypt1, - faruchar *plain2, - ulong arraysize, - ulong nloops, - IDEAkey Z, - IDEAkey DK) -{ -register ulong i; -register ulong j; -ulong elapsed; -#ifdef DEBUG -int status=0; -#endif - -/* -** Start the stopwatch. -*/ -elapsed=StartStopwatch(); - -/* -** Do everything for nloops. -*/ -for(i=0;i>16); - return(b-a+(b> 7); - Z+=i&8; - i&=7; -} -return; -} - -/**************** -** de_key_idea ** -***************** -** Compute IDEA decryption subkeys DK from encryption -** subkeys Z. -*/ -static void de_key_idea(IDEAkey Z, IDEAkey DK) -{ -IDEAkey TT; -int j; -u16 t1, t2, t3; -u16 *p; -p=(u16 *)(TT+KEYLEN); - -t1=inv(*Z++); -t2=-*Z++; -t3=-*Z++; -*--p=inv(*Z++); -*--p=t3; -*--p=t2; -*--p=t1; - -for(j=1;jarraysize,&systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - ErrorExit(); -} -comparray=(farchar *)AllocateMemory(lochuffstruct->arraysize,&systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - FreeMemory(plaintext,&systemerror); - ErrorExit(); -} -decomparray=(farchar *)AllocateMemory(lochuffstruct->arraysize,&systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - FreeMemory(plaintext,&systemerror); - FreeMemory(comparray,&systemerror); - ErrorExit(); -} - -hufftree=(huff_node *)AllocateMemory(sizeof(huff_node) * 512, - &systemerror); -if(systemerror) -{ ReportError(errorcontext,systemerror); - FreeMemory(plaintext,&systemerror); - FreeMemory(comparray,&systemerror); - FreeMemory(decomparray,&systemerror); - ErrorExit(); -} - -/* -** Build the plaintext buffer. Since we want this to -** actually be able to compress, we'll use the -** wordcatalog to build the plaintext stuff. -*/ -/* -** Reset random number generator so things repeat. -** added by Uwe F. Mayer -*/ -randnum((int32)13); -create_text_block(plaintext,lochuffstruct->arraysize-1,(ushort)500); -plaintext[lochuffstruct->arraysize-1L]='\0'; -plaintextlen=lochuffstruct->arraysize; - -/* -** See if we need to perform self adjustment loop. -*/ -if(lochuffstruct->adjust==0) -{ - /* - ** Do self-adjustment. This involves initializing the - ** # of loops and increasing the loop count until we - ** get a number of loops that we can use. - */ - for(lochuffstruct->loops=100L; - lochuffstruct->loopsloops+=10L) - if(DoHuffIteration(plaintext, - comparray, - decomparray, - lochuffstruct->arraysize, - lochuffstruct->loops, - hufftree)>global_min_ticks) break; -} - -/* -** All's well if we get here. Do the test. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoHuffIteration(plaintext, - comparray, - decomparray, - lochuffstruct->arraysize, - lochuffstruct->loops, - hufftree); - iterations+=(double)lochuffstruct->loops; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -FreeMemory((farvoid *)plaintext,&systemerror); -FreeMemory((farvoid *)comparray,&systemerror); -FreeMemory((farvoid *)decomparray,&systemerror); -FreeMemory((farvoid *)hufftree,&systemerror); -lochuffstruct->iterspersec=iterations / TicksToFracSecs(accumtime); - -if(lochuffstruct->adjust==0) - lochuffstruct->adjust=1; - -} - -/********************* -** create_text_line ** -********************** -** Create a random line of text, stored at *dt. The line may be -** no more than nchars long. -*/ -static void create_text_line(farchar *dt, - long nchars) -{ -long charssofar; /* # of characters so far */ -long tomove; /* # of characters to move */ -char myword[40]; /* Local buffer for words */ -farchar *wordptr; /* Pointer to word from catalog */ - -charssofar=0; - -do { -/* -** Grab a random word from the wordcatalog -*/ -/* wordptr=wordcatarray[abs_randwc((long)WORDCATSIZE)];*/ -wordptr=wordcatarray[abs_randwc((int32)WORDCATSIZE)]; -MoveMemory((farvoid *)myword, - (farvoid *)wordptr, - (unsigned long)strlen(wordptr)+1); - -/* -** Append a blank. -*/ -tomove=strlen(myword)+1; -myword[tomove-1]=' '; - -/* -** See how long it is. If its length+charssofar > nchars, we have -** to trim it. -*/ -if((tomove+charssofar)>nchars) - tomove=nchars-charssofar; -/* -** Attach the word to the current line. Increment counter. -*/ -MoveMemory((farvoid *)dt,(farvoid *)myword,(unsigned long)tomove); -charssofar+=tomove; -dt+=tomove; - -/* -** If we're done, bail out. Otherwise, go get another word. -*/ -} while(charssofartblen) - linelen=tblen-bytessofar; - -if(linelen>1) -{ - create_text_line(tb,linelen); -} -tb+=linelen-1; /* Add the carriage return */ -*tb++='\n'; - -bytessofar+=linelen; - -} while(bytessofar>3; -bitnumb=bitoffset % 8; - -/* -** Set or clear -*/ -if(bitchar=='1') - comparray[byteoffset]|=(1<>3; -bitnumb=bitoffset % 8; - -/* -** Fetch -*/ -return((1<adjust==0) -{ - /* - ** Do self-adjustment. This involves initializing the - ** # of loops and increasing the loop count until we - ** get a number of loops that we can use. - */ - for(locnnetstruct->loops=1L; - locnnetstruct->loopsloops++) - { /*randnum(3L); */ - randnum((int32)3); - if(DoNNetIteration(locnnetstruct->loops) - >global_min_ticks) break; - } -} - -/* -** All's well if we get here. Do the test. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - /* randnum(3L); */ /* Gotta do this for Neural Net */ - randnum((int32)3); /* Gotta do this for Neural Net */ - accumtime+=DoNNetIteration(locnnetstruct->loops); - iterations+=(double)locnnetstruct->loops; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -locnnetstruct->iterspersec=iterations / TicksToFracSecs(accumtime); - -if(locnnetstruct->adjust==0) - locnnetstruct->adjust=1; - - -return; -} - -/******************** -** DoNNetIteration ** -********************* -** Do a single iteration of the neural net benchmark. -** By iteration, we mean a "learning" pass. -*/ -static ulong DoNNetIteration(ulong nloops) -{ -ulong elapsed; /* Elapsed time */ -int patt; - -/* -** Run nloops learning cycles. Notice that, counted with -** the learning cycle is the weight randomization and -** zeroing of changes. This should reduce clock jitter, -** since we don't have to stop and start the clock for -** each iteration. -*/ -elapsed=StartStopwatch(); -while(nloops--) -{ - randomize_wts(); - zero_changes(); - iteration_count=1; - learned = F; - numpasses = 0; - while (learned == F) - { - for (patt=0; patt tot_error) - tot_error = -error; /* worst error this pattern */ - } - else - { - sum += error; - if (error > tot_error) - tot_error = error; /* worst error this pattern */ - } -} -avg_out_error[patt] = sum/OUT_SIZE; -tot_out_error[patt] = tot_error; -return; -} - -/*********************** -** worst_pass_error() ** -************************ -** Find the worst and average error in the pass and save it -**/ -static void worst_pass_error() -{ -double error,sum; - -int i; - -error = 0.0; -sum = 0.0; -for (i=0; i error) error = tot_out_error[i]; - sum += avg_out_error[i]; -} -worst_error = error; -average_error = sum/numpats; -return; -} - -/******************* -** do_mid_error() ** -******************** -** Compute the error for the middle layer neurodes -** This is based on the output errors computed above. -** Note that the derivative of the sigmoid f(x) is -** f'(x) = f(x)(1 - f(x)) -** Recall that f(x) is merely the output of the middle -** layer neurode on the forward pass. -**/ -static void do_mid_error() -{ -double sum; -int neurode, i; - -for (neurode=0; neurode= STOP) result = F; - if (tot_out_error[i] >= 16.0) error = T; -} - -if (error == T) result = ERR; - - -#ifdef DEBUG -/* printf("\n Error this pass thru data: Worst: %8.3f; Average: %8.3f", - worst_error,average_error); -*/ -/* fprintf(outfile, - "\n Error this pass thru data: Worst: %8.3f; Average: %8.3f", - worst_error, average_error); */ -#endif - -return(result); -} - - -/******************* -** zero_changes() ** -******************** -** Zero out all the wt change arrays -**/ -static void zero_changes() -{ -int i,j; - -for (i = 0; i MAXPATS) - numpats = MAXPATS; - -for (patt=0; patt= 0.9) - in_pats[patt][i] = 0.9; - if (in_pats[patt][i] <= 0.1) - in_pats[patt][i] = 0.1; - } - element = 0; - vals_read = fscanf(infile,"%d %d %d %d %d %d %d %d", - &val1, &val2, &val3, &val4, &val5, &val6, &val7, &val8); - - out_pats[patt][element] = (double) val1; element++; - out_pats[patt][element] = (double) val2; element++; - out_pats[patt][element] = (double) val3; element++; - out_pats[patt][element] = (double) val4; element++; - out_pats[patt][element] = (double) val5; element++; - out_pats[patt][element] = (double) val6; element++; - out_pats[patt][element] = (double) val7; element++; - out_pats[patt][element] = (double) val8; element++; -} - -/* printf("\n Closing the input file now. "); */ - -fclose(infile); -return(0); -} - -/********************* -** initialize_net() ** -********************** -** Do all the initialization stuff before beginning -*/ -/* -static int initialize_net() -{ -int err_code; - -randomize_wts(); -zero_changes(); -err_code = read_data_file(); -iteration_count = 1; -return(err_code); -} -*/ - -/********************** -** display_mid_wts() ** -*********************** -** Display the weights on the middle layer neurodes -** NOTE: This routine is not used in the benchmark -** test -- RG -**/ -/* static void display_mid_wts() -{ -int neurode, weight, row, col; - -fprintf(outfile,"\n Weights of Middle Layer neurodes:"); - -for (neurode=0; neurodeadjust==0) -{ - loclustruct->numarrays=0; - for(i=1;i<=MAXLUARRAYS;i++) - { - abase=(fardouble *)AllocateMemory(sizeof(double) * - LUARRAYCOLS*LUARRAYROWS*(i+1),&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - LUFreeMem(a,b,(fardouble *)NULL,(fardouble *)NULL); - ErrorExit(); - } - bbase=(fardouble *)AllocateMemory(sizeof(double) * - LUARRAYROWS*(i+1),&systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - LUFreeMem(a,b,abase,(fardouble *)NULL); - ErrorExit(); - } - if(DoLUIteration(a,b,abase,bbase,i)>global_min_ticks) - { loclustruct->numarrays=i; - break; - } - /* - ** Not enough arrays...free them all and try again - */ - FreeMemory((farvoid *)abase,&systemerror); - FreeMemory((farvoid *)bbase,&systemerror); - } - /* - ** Were we able to do it? - */ - if(loclustruct->numarrays==0) - { printf("FPU:LU -- Array limit reached\n"); - LUFreeMem(a,b,abase,bbase); - ErrorExit(); - } -} -else -{ /* - ** Don't need to adjust -- just allocate the proper - ** number of arrays and proceed. - */ - abase=(fardouble *)AllocateMemory(sizeof(double) * - LUARRAYCOLS*LUARRAYROWS*loclustruct->numarrays, - &systemerror); - if(systemerror) - { ReportError(errorcontext,systemerror); - LUFreeMem(a,b,(fardouble *)NULL,(fardouble *)NULL); - ErrorExit(); - } - bbase=(fardouble *)AllocateMemory(sizeof(double) * - LUARRAYROWS*loclustruct->numarrays,&systemerror); - if(systemerror) - { - ReportError(errorcontext,systemerror); - LUFreeMem(a,b,abase,(fardouble *)NULL); - ErrorExit(); - } -} -/* -** All's well if we get here. Do the test. -*/ -accumtime=0L; -iterations=(double)0.0; - -do { - accumtime+=DoLUIteration(a,b,abase,bbase, - loclustruct->numarrays); - iterations+=(double)loclustruct->numarrays; -} while(TicksToSecs(accumtime)request_secs); - -/* -** Clean up, calculate results, and go home. Be sure to -** show that we don't have to rerun adjustment code. -*/ -loclustruct->iterspersec=iterations / TicksToFracSecs(accumtime); - -if(loclustruct->adjust==0) - loclustruct->adjust=1; - -LUFreeMem(a,b,abase,bbase); -return; -} - -/************** -** LUFreeMem ** -*************** -** Release memory associated with LU benchmark. -*/ -static void LUFreeMem(fardouble *a, fardouble *b, - fardouble *abase,fardouble *bbase) -{ -int systemerror; - -FreeMemory((farvoid *)a,&systemerror); -FreeMemory((farvoid *)b,&systemerror); -FreeMemory((farvoid *)LUtempvv,&systemerror); - -if(abase!=(fardouble *)NULL) FreeMemory((farvoid *)abase,&systemerror); -if(bbase!=(fardouble *)NULL) FreeMemory((farvoid *)bbase,&systemerror); -return; -} - -/****************** -** DoLUIteration ** -******************* -** Perform an iteration of the LU decomposition benchmark. -** An iteration refers to the repeated solution of several -** identical matrices. -*/ -static ulong DoLUIteration(fardouble *a,fardouble *b, - fardouble *abase, fardouble *bbase, - ulong numarrays) -{ -fardouble *locabase; -fardouble *locbbase; -LUdblptr ptra; /* For converting ptr to 2D array */ -ulong elapsed; -ulong j,i; /* Indexes */ - - -/* -** Move the seed arrays (a & b) into the destination -** arrays; -*/ -for(j=0;j big) - big=fabs(a[i][j]); - /* Bail out on singular matrix */ - if(big==(double)0.0) return(0); - LUtempvv[i]=1.0/big; -} - -/* -** Crout's algorithm...loop over columns. -*/ -for(j=0;j=big) - { big=dum; - imax=i; - } - } - if(j!=imax) /* Interchange rows if necessary */ - { for(k=0;k=0;i--) -{ - sum=b[i]; - if(i!=(n-1)) - for(j=(i+1);j /* +#include +#include +#include */ +#include +#include "nmglobal.h" +#include "nbench1.h" + +/* +** The Neural Net test requires an input data file. +** The name is specified here. +*/ +char *inpath="NNET.DAT"; + +/******************************** +** BACK PROPAGATION NEURAL NET ** +********************************* +** This code is a modified version of the code +** that was submitted to BYTE Magazine by +** Maureen Caudill. It accomanied an article +** that I CANNOT NOW RECALL. +** The author's original heading/comment was +** as follows: +** +** Backpropagation Network +** Written by Maureen Caudill +** in Think C 4.0 on a Macintosh +** +** (c) Maureen Caudill 1988-1991 +** This network will accept 5x7 input patterns +** and produce 8 bit output patterns. +** The source code may be copied or modified without restriction, +** but no fee may be charged for its use. +** +** ++++++++++++++ +** I have modified the code so that it will work +** on systems other than a Macintosh -- RG +*/ + +/*********** +** DoNNet ** +************ +** Perform the neural net benchmark. +** Note that this benchmark is one of the few that +** requires an input file. That file is "NNET.DAT" and +** should be on the local directory (from which the +** benchmark program in launched). +*/ +void DoNNET(void) +{ +NNetStruct *locnnetstruct; /* Local ptr to global data */ +char *errorcontext; +ulong accumtime; +double iterations; + +/* +** Link to global data +*/ +locnnetstruct=&global_nnetstruct; + +/* +** Set error context +*/ +errorcontext="CPU:NNET"; + +/* +** Init random number generator. +** NOTE: It is important that the random number generator +** be re-initialized for every pass through this test. +** The NNET algorithm uses the random number generator +** to initialize the net. Results are sensitive to +** the initial neural net state. +*/ +/* randnum(3L); */ +randnum((int32)3); + +/* +** Read in the input and output patterns. We'll do this +** only once here at the beginning. These values don't +** change once loaded. +*/ +if(read_data_file()!=0) + ErrorExit(); + + +/* +** See if we need to perform self adjustment loop. +*/ +if(locnnetstruct->adjust==0) +{ + /* + ** Do self-adjustment. This involves initializing the + ** # of loops and increasing the loop count until we + ** get a number of loops that we can use. + */ + for(locnnetstruct->loops=1L; + locnnetstruct->loopsloops++) + { /*randnum(3L); */ + randnum((int32)3); + if(DoNNetIteration(locnnetstruct->loops) + >global_min_ticks) break; + } +} + +/* +** All's well if we get here. Do the test. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + /* randnum(3L); */ /* Gotta do this for Neural Net */ + randnum((int32)3); /* Gotta do this for Neural Net */ + accumtime+=DoNNetIteration(locnnetstruct->loops); + iterations+=(double)locnnetstruct->loops; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +locnnetstruct->iterspersec=iterations / TicksToFracSecs(accumtime); + +if(locnnetstruct->adjust==0) + locnnetstruct->adjust=1; + + +return; +} + +/******************** +** DoNNetIteration ** +********************* +** Do a single iteration of the neural net benchmark. +** By iteration, we mean a "learning" pass. +*/ +static ulong DoNNetIteration(ulong nloops) +{ +ulong elapsed; /* Elapsed time */ +int patt; + +/* +** Run nloops learning cycles. Notice that, counted with +** the learning cycle is the weight randomization and +** zeroing of changes. This should reduce clock jitter, +** since we don't have to stop and start the clock for +** each iteration. +*/ +elapsed=StartStopwatch(); +while(nloops--) +{ + randomize_wts(); + zero_changes(); + iteration_count=1; + learned = F; + numpasses = 0; + while (learned == F) + { + for (patt=0; patt tot_error) + tot_error = -error; /* worst error this pattern */ + } + else + { + sum += error; + if (error > tot_error) + tot_error = error; /* worst error this pattern */ + } +} +avg_out_error[patt] = sum/OUT_SIZE; +tot_out_error[patt] = tot_error; +return; +} + +/*********************** +** worst_pass_error() ** +************************ +** Find the worst and average error in the pass and save it +**/ +static void worst_pass_error() +{ +double error,sum; + +int i; + +error = 0.0; +sum = 0.0; +for (i=0; i error) error = tot_out_error[i]; + sum += avg_out_error[i]; +} +worst_error = error; +average_error = sum/numpats; +return; +} + +/******************* +** do_mid_error() ** +******************** +** Compute the error for the middle layer neurodes +** This is based on the output errors computed above. +** Note that the derivative of the sigmoid f(x) is +** f'(x) = f(x)(1 - f(x)) +** Recall that f(x) is merely the output of the middle +** layer neurode on the forward pass. +**/ +static void do_mid_error() +{ +double sum; +int neurode, i; + +for (neurode=0; neurode= STOP) result = F; + if (tot_out_error[i] >= 16.0) error = T; +} + +if (error == T) result = ERR; + + +#ifdef DEBUG +/* printf("\n Error this pass thru data: Worst: %8.3f; Average: %8.3f", + worst_error,average_error); +*/ +/* fprintf(outfile, + "\n Error this pass thru data: Worst: %8.3f; Average: %8.3f", + worst_error, average_error); */ +#endif + +return(result); +} + + +/******************* +** zero_changes() ** +******************** +** Zero out all the wt change arrays +**/ +static void zero_changes() +{ +int i,j; + +for (i = 0; i MAXPATS) + numpats = MAXPATS; + +for (patt=0; patt= 0.9) + in_pats[patt][i] = 0.9; + if (in_pats[patt][i] <= 0.1) + in_pats[patt][i] = 0.1; + } + element = 0; + vals_read = fscanf(infile,"%d %d %d %d %d %d %d %d", + &val1, &val2, &val3, &val4, &val5, &val6, &val7, &val8); + + out_pats[patt][element] = (double) val1; element++; + out_pats[patt][element] = (double) val2; element++; + out_pats[patt][element] = (double) val3; element++; + out_pats[patt][element] = (double) val4; element++; + out_pats[patt][element] = (double) val5; element++; + out_pats[patt][element] = (double) val6; element++; + out_pats[patt][element] = (double) val7; element++; + out_pats[patt][element] = (double) val8; element++; +} + +/* printf("\n Closing the input file now. "); */ + +fclose(infile); +return(0); +} + +/********************* +** initialize_net() ** +********************** +** Do all the initialization stuff before beginning +*/ +/* +static int initialize_net() +{ +int err_code; + +randomize_wts(); +zero_changes(); +err_code = read_data_file(); +iteration_count = 1; +return(err_code); +} +*/ + +/********************** +** display_mid_wts() ** +*********************** +** Display the weights on the middle layer neurodes +** NOTE: This routine is not used in the benchmark +** test -- RG +**/ +/* static void display_mid_wts() +{ +int neurode, weight, row, col; + +fprintf(outfile,"\n Weights of Middle Layer neurodes:"); + +for (neurode=0; neurode +#include +/* +#include +#include +#include +#include +*/ +#include "nmglobal.h" +#include "nbench1.h" + +/********************* +** NUMERIC HEAPSORT ** +********************** +** This test implements a heapsort algorithm, performed on an +** array of longs. +*/ + +/************** +** DoNumSort ** +*************** +** This routine performs the CPU numeric sort test. +** NOTE: Last version incorrectly stated that the routine +** returned result in # of longword sorted per second. +** Not so; the routine returns # of iterations per sec. +*/ + +void DoNumSort(void) +{ +SortStruct *numsortstruct; /* Local pointer to global struct */ +long *arraybase; /* Base pointers of array */ +long accumtime; /* Accumulated time */ +double iterations; /* Iteration counter */ +char *errorcontext; /* Error context string pointer */ +int systemerror; /* For holding error codes */ + +/* +** Link to global structure +*/ +numsortstruct=&global_numsortstruct; + +/* +** Set the error context string. +*/ +errorcontext="CPU:Numeric Sort"; + +/* +** See if we need to do self adjustment code. +*/ +if(numsortstruct->adjust==0) +{ + /* + ** Self-adjustment code. The system begins by sorting 1 + ** array. If it does that in no time, then two arrays + ** are built and sorted. This process continues until + ** enough arrays are built to handle the tolerance. + */ + numsortstruct->numarrays=1; + while(1) + { + /* + ** Allocate space for arrays + */ + arraybase=(long *)AllocateMemory(sizeof(long) * + numsortstruct->numarrays * numsortstruct->arraysize, + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)arraybase, + &systemerror); + } + + /* + ** Do an iteration of the numeric sort. If the + ** elapsed time is less than or equal to the permitted + ** minimum, then allocate for more arrays and + ** try again. + */ + if(DoNumSortIteration(arraybase, + numsortstruct->arraysize, + numsortstruct->numarrays)>global_min_ticks) + break; /* We're ok...exit */ + + FreeMemory((void *)arraybase,&systemerror); + if(numsortstruct->numarrays++>NUMNUMARRAYS) + { printf("CPU:NSORT -- NUMNUMARRAYS hit.\n"); + } + } +} +else +{ /* + ** Allocate space for arrays + */ + arraybase=(long *)AllocateMemory(sizeof(long) * + numsortstruct->numarrays * numsortstruct->arraysize, + &systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + FreeMemory((void *)arraybase, + &systemerror); + } + +} +/* +** All's well if we get here. Repeatedly perform sorts until the +** accumulated elapsed time is greater than # of seconds requested. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoNumSortIteration(arraybase, + numsortstruct->arraysize, + numsortstruct->numarrays); + iterations+=(double)1.0; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. Be sure to +** show that we don't have to rerun adjustment code. +*/ +FreeMemory((void *)arraybase,&systemerror); + +numsortstruct->sortspersec=iterations * + (double)numsortstruct->numarrays / TicksToFracSecs(accumtime); + +if(numsortstruct->adjust==0) + numsortstruct->adjust=1; + +#ifdef DEBUG +if (numsort_status==0) printf("Numeric sort: OK\n"); +numsort_status=0; +#endif +return; +} + +/*********************** +** DoNumSortIteration ** +************************ +** This routine executes one iteration of the numeric +** sort benchmark. It returns the number of ticks +** elapsed for the iteration. +*/ +static unsigned long DoNumSortIteration(long *arraybase, + unsigned long arraysize, + unsigned int numarrays) +{ +unsigned long elapsed; /* Elapsed ticks */ +unsigned long i; +/* +** Load up the array with random numbers +*/ +LoadNumArrayWithRand(arraybase,arraysize,numarrays); + +/* +** Start the stopwatch +*/ +elapsed=StartStopwatch(); + +/* +** Execute a heap of heapsorts +*/ +for(i=0;i0; --i) + NumSift(array,i,top); + +/* +** Repeatedly extract maximum from heap and place it at the +** end of the array. When we get done, we'll have a sorted +** array. +*/ +for(i=top; i>0; --i) +{ NumSift(array,bottom,i); + temp=*array; /* Perform exchange */ + *array=*(array+i); + *(array+i)=temp; +} +return; +} + +/************ +** NumSift ** +************* +** Peforms the sift operation on a numeric array, +** constructing a heap in the array. +*/ +static void NumSift(long *array, /* Array of numbers */ + unsigned long i, /* Minimum of array */ + unsigned long j) /* Maximum of array */ +{ +unsigned long k; +long temp; /* Used for exchange */ + +while((i+i)<=j) +{ + k=i+i; + if(k +/*#include +#include +#include +#include +#include */ +#include "nmglobal.h" +#include "nbench1.h" + +#ifdef DEBUG +static int numsort_status=0; +static int stringsort_status=0; +#endif + +/******************** +** STRING HEAPSORT ** +********************/ + +/***************** +** DoStringSort ** +****************** +** This routine performs the CPU string sort test. +** Arguments: +** requested_secs = # of seconds to execute test +** stringspersec = # of strings per second sorted (RETURNED) +*/ +void DoStringSort(void) +{ + +SortStruct *strsortstruct; /* Local for sort structure */ +unsigned char *arraybase; /* Base pointer of char array */ +long accumtime; /* Accumulated time */ +double iterations; /* # of iterations */ +char *errorcontext; /* Error context string pointer */ +int systemerror; /* For holding error code */ + +/* +** Link to global structure +*/ +strsortstruct=&global_strsortstruct; + +/* +** Set the error context +*/ +errorcontext="CPU:String Sort"; + +/* +** See if we have to perform self-adjustment code +*/ +if(strsortstruct->adjust==0) +{ + /* + ** Initialize the number of arrays. + */ + strsortstruct->numarrays=1; + while(1) + { + /* + ** Allocate space for array. We'll add an extra 100 + ** bytes to protect memory as strings move around + ** (this can happen during string adjustment) + */ + arraybase=(unsigned char *)AllocateMemory((strsortstruct->arraysize+100L) * + (long)strsortstruct->numarrays,&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + } + + /* + ** Do an iteration of the string sort. If the + ** elapsed time is less than or equal to the permitted + ** minimum, then de-allocate the array, reallocate a + ** an additional array, and try again. + */ + if(DoStringSortIteration(arraybase, + strsortstruct->numarrays, + strsortstruct->arraysize)>global_min_ticks) + break; /* We're ok...exit */ + + FreeMemory((void *)arraybase,&systemerror); + strsortstruct->numarrays+=1; + } +} +else +{ + /* + ** We don't have to perform self adjustment code. + ** Simply allocate the space for the array. + */ + arraybase=(unsigned char *)AllocateMemory((strsortstruct->arraysize+100L) * + (long)strsortstruct->numarrays,&systemerror); + if(systemerror) + { ReportError(errorcontext,systemerror); + } +} +/* +** All's well if we get here. Repeatedly perform sorts until the +** accumulated elapsed time is greater than # of seconds requested. +*/ +accumtime=0L; +iterations=(double)0.0; + +do { + accumtime+=DoStringSortIteration(arraybase, + strsortstruct->numarrays, + strsortstruct->arraysize); + iterations+=(double)strsortstruct->numarrays; +} while(TicksToSecs(accumtime)request_secs); + +/* +** Clean up, calculate results, and go home. +** Set flag to show we don't need to rerun adjustment code. +*/ +FreeMemory((void *)arraybase,&systemerror); +strsortstruct->sortspersec=iterations / (double)TicksToFracSecs(accumtime); +if(strsortstruct->adjust==0) + strsortstruct->adjust=1; +#ifdef DEBUG +if (stringsort_status==0) printf("String sort: OK\n"); +stringsort_status=0; +#endif +return; +} + +/************************** +** DoStringSortIteration ** +*************************** +** This routine executes one iteration of the string +** sort benchmark. It returns the number of ticks +** Note that this routine also builds the offset pointer +** array. +*/ +static unsigned long DoStringSortIteration(unsigned char *arraybase, + unsigned int numarrays,unsigned long arraysize) +{ +unsigned long *optrarray; /* Offset pointer array */ +unsigned long elapsed; /* Elapsed ticks */ +unsigned long nstrings; /* # of strings in array */ +int syserror; /* System error code */ +unsigned int i; /* Index */ +unsigned long *tempobase; /* Temporary offset pointer base */ +unsigned char *tempsbase; /* Temporary string base pointer */ + +/* +** Load up the array(s) with random numbers +*/ +optrarray=LoadStringArray(arraybase,numarrays,&nstrings,arraysize); + +/* +** Set temp base pointers...they will be modified as the +** benchmark proceeds. +*/ +tempobase=optrarray; +tempsbase=arraybase; + +/* +** Start the stopwatch +*/ +elapsed=StartStopwatch(); + +/* +** Execute heapsorts +*/ +for(i=0;i=arraysize) + { stringlength=(unsigned char)((arraysize-curroffset-1L) & + 0xFF); + fullflag=1; /* Indicates a full */ + } + + /* + ** Store length at curroffset and advance current offset. + */ + *(strarray+curroffset)=stringlength; + curroffset++; + + /* + ** Fill up the rest of the string with random bytes. + */ + for(i=0;i0; --i) + strsift(optrarray,strarray,numstrings,i,top); + +/* +** Repeatedly extract maximum from heap and place it at the +** end of the array. When we get done, we'll have a sorted +** array. +*/ +for(i=top; i>0; --i) +{ + strsift(optrarray,strarray,numstrings,0,i); + + /* temp = string[0] */ + tlen=*strarray; + MoveMemory((void *)&temp[0], /* Perform exchange */ + (void *)strarray, + (unsigned long)(tlen+1)); + + + /* string[0]=string[i] */ + tlen=*(strarray+*(optrarray+i)); + stradjust(optrarray,strarray,numstrings,0,tlen); + MoveMemory((void *)strarray, + (void *)(strarray+*(optrarray+i)), + (unsigned long)(tlen+1)); + + /* string[i]=temp */ + tlen=temp[0]; + stradjust(optrarray,strarray,numstrings,i,tlen); + MoveMemory((void *)(strarray+*(optrarray+i)), + (void *)&temp[0], + (unsigned long)(tlen+1)); + +} +return; +} + +/**************** +** str_is_less ** +***************** +** Pass this function: +** 1) A pointer to an array of offset pointers +** 2) A pointer to a string array +** 3) The number of elements in the string array +** 4) Offsets to two strings (a & b) +** This function returns TRUE if string a is < string b. +*/ +static int str_is_less(unsigned long *optrarray, /* Offset pointers */ + unsigned char *strarray, /* String array */ + unsigned long numstrings, /* # of strings */ + unsigned long a, unsigned long b) /* Offsets */ +{ +int slen; /* String length */ + +/* +** Determine which string has the minimum length. Use that +** to call strncmp(). If they match up to that point, the +** string with the longer length wins. +*/ +slen=(int)*(strarray+*(optrarray+a)); +if(slen > (int)*(strarray+*(optrarray+b))) + slen=(int)*(strarray+*(optrarray+b)); + +slen=strncmp((char *)(strarray+*(optrarray+a)), + (char *)(strarray+*(optrarray+b)),slen); + +if(slen==0) +{ + /* + ** They match. Return true if the length of a + ** is greater than the length of b. + */ + if(*(strarray+*(optrarray+a)) > + *(strarray+*(optrarray+b))) + return(TRUE); + return(FALSE); +} + +if(slen<0) return(TRUE); /* a is strictly less than b */ + +return(FALSE); /* Only other possibility */ +} + +/************ +** strsift ** +************* +** Pass this function: +** 1) A pointer to an array of offset pointers +** 2) A pointer to a string array +** 3) The number of elements in the string array +** 4) Offset within which to sort. +** Sift the array within the bounds of those offsets (thus +** building a heap). +*/ +static void strsift(unsigned long *optrarray, /* Offset pointers */ + unsigned char *strarray, /* String array */ + unsigned long numstrings, /* # of strings */ + unsigned long i, unsigned long j) /* Offsets */ +{ +unsigned long k; /* Temporaries */ +unsigned char temp[80]; +unsigned char tlen; /* For string lengths */ + + +while((i+i)<=j) +{ + k=i+i; + if(k