nbench1.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,217 行 · 第 1/5 页

C
2,217
字号

/*
** 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "nmglobal.h"
#include "nbench1.h"
#include "wordcat.h"
#include "timer.h"
#include "report.h"

#ifndef MAC
#include <mem.h>
#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 */
double wat_time;
double tot_time;

/*
** 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, NULL)>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;
tot_time = (double)0.0;

do {
        accumtime+=DoNumSortIteration(arraybase,
                numsortstruct->arraysize,
                numsortstruct->numarrays, &wat_time);
        iterations+=(double)1.0;
	tot_time += wat_time;
} while(TicksToSecs(accumtime)<numsortstruct->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);
tot_time /= ( (double)(numsortstruct->numarrays) * iterations );
ReportTime( tot_time );

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,
		double *wat_time)
{
ulong elapsed;          /* Elapsed ticks */
ulong i;
/*
** Load up the array with random numbers
*/
LoadNumArrayWithRand(arraybase,arraysize,numarrays);

/*
** Start the stopwatch
*/
elapsed=StartStopwatch();
TimerOn();

/*
** Execute a heap of heapsorts
*/
for(i=0;i<numarrays;i++)
        NumHeapSort(arraybase+i*arraysize,0L,arraysize-1L);

/*
** Get elapsed time
*/
TimerOff();
if( wat_time ) {
    *wat_time = TimerElapsed();
}
elapsed=StopStopwatch(elapsed);
#ifdef DEBUG
{

        for(i=0;i<arraysize-1;i++)
        {       /*
                ** Compare to check for proper
                ** sort.
                */
                if(arraybase[i+1]<arraybase[i])
                {       printf("Sort Error\n");
                        break;
                }
        }
}
#endif

return(elapsed);
}

/*************************
** LoadNumArrayWithRand **
**************************
** Load up an array with random longs.
*/
static void LoadNumArrayWithRand(farlong *array,     /* Pointer to arrays */
                ulong arraysize,
                uint numarrays)         /* # of elements in array */
{
long i;                 /* Used for index */
farlong *darray;        /* Destination array pointer */
/*
** Initialize the random number generator
*/
randnum(13L);

/*
** Load up first array with randoms
*/
for(i=0L;i<arraysize;i++)
        array[i]=randnum(0L);

/*
** Now, if there's more than one array to load, copy the
** first into each of the others.
*/
darray=array;
while(--numarrays)
{       darray+=arraysize;
        for(i=0L;i<arraysize;i++)
                darray[i]=array[i];
}
        
return;
}

/****************
** NumHeapSort **
*****************
** Pass this routine a pointer to an array of long
** integers.  Also pass in minimum and maximum offsets.
** This routine performs a heap sort on that array.
*/
static void NumHeapSort(farlong *array,
        ulong bottom,           /* Lower bound */
        ulong top)              /* Upper bound */
{
ulong temp;                     /* Used to exchange elements */
ulong i;                        /* Loop index */

/*
** First, build a heap in the array
*/
for(i=(top/2L); i>0; --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<j)
                if(array[k]<array[k+1L])
                        ++k;
        if(array[i]<array[k])
        {
                temp=array[k];
                array[k]=array[i];
                array[i]=temp;
                i=k;
        }
        else
                i=j+1;
}
return;
}

/********************
** 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 */
double wat_time;
double tot_time;

/*
** 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,NULL)>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;
tot_time=(double)0.0;

do {
        accumtime+=DoStringSortIteration(arraybase,
                                strsortstruct->numarrays,
                                strsortstruct->arraysize, &wat_time);
	tot_time += wat_time;
        iterations+=(double)strsortstruct->numarrays;
} while(TicksToSecs(accumtime)<strsortstruct->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);
tot_time /= iterations;
ReportTime( tot_time );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?