//
/*
** nbench1.c
*/
/********************************
** BYTEmark (tm) **
** BYTE NATIVE MODE BENCHMARKS **
** VERSION 2 **
** **
** Included in this source **
** file: **
** Numeric Heapsort **
** String Heapsort **
** Bitfield test **
** Floating point emulation **
** Fourier coefficients **
** Assignment algorithm **
** IDEA Encyption **
** Huffman compression **
** Back prop. neural net **
** LU Decomposition **
** (linear equations) **
** ---------- **
** Rick Grehan, BYTE Magazine **
*********************************
*/
/*
** INCLUDES
*/
#include
#include
#include
#include
#include "nmglobal.h"
#include "nbench1.h"
#include "wordcat.h"
/*
#ifndef MAC
#include
#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;
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(k
/********************
** 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 */
faruchar *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=(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;
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(k
/************************
** 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 */
farulong *bitarraybase; /* Base of bitmap array */
farulong *bitoparraybase; /* Base of bitmap operations array */
ulong nbitops; /* # of bitfield operations */
ulong accumtime; /* Accumulated time in ticks */
double iterations; /* # of iterations */
char *errorcontext; /* Error context string */
int systemerror; /* For holding error codes */
/*
** 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=(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.
*/
if(DoBitfieldIteration(bitarraybase,
bitoparraybase,
locbitopstruct->bitoparraysize,
&nbitops)>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)
*/
for (i=0;i>6; /* Index is number /64 */
bindex=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 % 32; /* 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<
/*****************************
** 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 */
ulong accumtime; /* Accumulated time in ticks */
double iterations; /* # of iterations */
ulong tickcount; /* # of ticks */
char *errorcontext; /* Error context string pointer */
int systemerror; /* For holding error code */
ulong 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((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;
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;i
/*************************
** 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
/********************
** IDEA Encryption **
*********************
** IDEA - International Data Encryption Algorithm.
** Based on code presented in Applied Cryptography by Bruce Schneier.
** Which was based on code developed by Xuejia Lai and James L. Massey.
** Other modifications made by Colin Plumb.
**
*/
/***********
** DoIDEA **
************
** Perform IDEA encryption. Note that we time encryption & decryption
** time as being a single loop.
*/
void DoIDEA(void)
{
IDEAStruct *locideastruct; /* Loc pointer to global structure */
int i;
IDEAkey Z,DK;
u16 userkey[8];
ulong accumtime;
double iterations;
char *errorcontext;
int systemerror;
faruchar *plain1; /* First plaintext buffer */
faruchar *crypt1; /* Encryption buffer */
faruchar *plain2; /* Second plaintext buffer */
/*
** Link to global data
*/
locideastruct=&global_ideastruct;
/*
** Set error context
*/
errorcontext="CPU:IDEA";
/*
** Re-init random-number generator.
*/
randnum(3L);
/*
** Build an encryption/decryption key
*/
for (i=0;i<8;i++)
userkey[i]=(u16)(abs_randwc(60000L) & 0xFFFF);
for(i=0;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;
/*
** 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
/************************
** 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;
ulong accumtime;
double iterations;
farchar *comparray;
farchar *decomparray;
farchar *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=(farchar *)AllocateMemory(lochuffstruct->arraysize,&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.
*/
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)];
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<
/********************************
** 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;
int systemerror;
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);
/*
** 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);
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 */
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
/***********************
** 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;
double *a;
double *b;
double *abase;
double *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=(double *)AllocateMemory(sizeof(double) * LUARRAYCOLS * LUARRAYROWS,
&systemerror);
b=(double *)AllocateMemory(sizeof(double) * LUARRAYROWS,
&systemerror);
n=LUARRAYROWS;
/*
** 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=(double *)AllocateMemory(sizeof(double) *
LUARRAYCOLS*LUARRAYROWS*(i+1),&systemerror);
if(systemerror)
{ ReportError(errorcontext,systemerror);
LUFreeMem(a,b,(double *)NULL,(double *)NULL);
ErrorExit();
}
bbase=(double *)AllocateMemory(sizeof(double) *
LUARRAYROWS*(i+1),&systemerror);
if(systemerror)
{ ReportError(errorcontext,systemerror);
LUFreeMem(a,b,abase,(double *)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=(double *)AllocateMemory(sizeof(double) *
LUARRAYCOLS*LUARRAYROWS*loclustruct->numarrays,
&systemerror);
if(systemerror)
{ ReportError(errorcontext,systemerror);
LUFreeMem(a,b,(double *)NULL,(double *)NULL);
ErrorExit();
}
bbase=(double *)AllocateMemory(sizeof(double) *
LUARRAYROWS*loclustruct->numarrays,&systemerror);
if(systemerror)
{
ReportError(errorcontext,systemerror);
LUFreeMem(a,b,abase,(double *)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(double *a, double *b,
double *abase,double *bbase)
{
int systemerror;
FreeMemory((farvoid *)a,&systemerror);
FreeMemory((farvoid *)b,&systemerror);
if(abase!=(double *)NULL) FreeMemory((farvoid *)abase,&systemerror);
if(bbase!=(double *)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(double *a,double *b,
double *abase, double *bbase,
ulong numarrays)
{
double *locabase;
double *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);
vv[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