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 + -
显示快捷键?