nbench1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,217 行 · 第 1/5 页
C
2,217 行
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, double *wat_time)
{
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();
TimerOn();
/*
** Execute heapsorts
*/
for(i=0;i<numarrays;i++)
{ StrHeapSort(tempobase,tempsbase,nstrings,0L,nstrings-1);
tempobase+=nstrings; /* Advance base pointers */
tempsbase+=arraysize+100;
}
/*
** Record elapsed time
*/
TimerOff();
elapsed=StopStopwatch(elapsed);
#ifdef DEBUG
{
unsigned long i;
for(i=0;i<nstrings-1;i++)
{ /*
** Compare strings to check for proper
** sort.
*/
if(str_is_less(optrarray,arraybase,nstrings,i+1,i))
{ printf("Sort Error\n");
break;
}
}
}
#endif
/*
** Release the offset pointer array built by
** LoadStringArray()
*/
FreeMemory((farvoid *)optrarray,&syserror);
if( wat_time ) {
*wat_time = TimerElapsed();
}
/*
** Return elapsed ticks.
*/
return(elapsed);
}
/********************
** LoadStringArray **
*********************
** Initialize the string array with random strings of
** varying sizes.
** Returns the pointer to the offset pointer array.
** Note that since we're creating a number of arrays, this
** routine builds one array, then copies it into the others.
*/
static farulong *LoadStringArray(faruchar *strarray, /* String array */
uint numarrays, /* # of arrays */
ulong *nstrings, /* # of strings */
ulong arraysize) /* Size of array */
{
faruchar *tempsbase; /* Temporary string base pointer */
farulong *optrarray; /* Local for pointer */
farulong *tempobase; /* Temporary offset pointer base pointer */
unsigned long curroffset; /* Current offset */
int fullflag; /* Indicates full array */
unsigned char stringlength; /* Length of string */
unsigned char i; /* Index */
unsigned long j; /* Another index */
unsigned int k; /* Yet another index */
unsigned int l; /* Ans still one more index */
int systemerror; /* For holding error code */
/*
** Initialize random number generator.
*/
randnum(13L);
/*
** Start with no strings. Initialize our current offset pointer
** to 0.
*/
*nstrings=0L;
curroffset=0L;
fullflag=0;
do
{
/*
** Allocate a string with a random length no
** shorter than 4 bytes and no longer than
** 80 bytes. Note we have to also make sure
** there's room in the array.
*/
stringlength=(unsigned char)(1+abs_randwc(76L) & 0xFFL);
if((unsigned long)stringlength+curroffset+1L>=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;i<stringlength;i++)
{ *(strarray+curroffset)=
(unsigned char)(abs_randwc((long)0xFE));
curroffset++;
}
/*
** Increment the # of strings counter.
*/
*nstrings+=1L;
} while(fullflag==0);
/*
** We now have initialized a single full array. If there
** is more than one array, copy the original into the
** others.
*/
k=1;
tempsbase=strarray;
while(k<numarrays)
{ tempsbase+=arraysize+100; /* Set base */
for(l=0;l<arraysize;l++)
tempsbase[l]=strarray[l];
k++;
}
/*
** Now the array is full, allocate enough space for an
** offset pointer array.
*/
optrarray=(farulong *)AllocateMemory(*nstrings * sizeof(unsigned long) *
numarrays,
&systemerror);
if(systemerror)
{ ReportError("CPU:Stringsort",systemerror);
FreeMemory((void *)strarray,&systemerror);
ErrorExit();
}
/*
** Go through the newly-built string array, building
** offsets and putting them into the offset pointer
** array.
*/
curroffset=0;
for(j=0;j<*nstrings;j++)
{ *(optrarray+j)=curroffset;
curroffset+=(unsigned long)(*(strarray+curroffset))+1L;
}
/*
** As above, we've made one copy of the offset pointers,
** so duplicate this array in the remaining ones.
*/
k=1;
tempobase=optrarray;
while(k<numarrays)
{ tempobase+=*nstrings;
for(l=0;l<*nstrings;l++)
tempobase[l]=optrarray[l];
k++;
}
/*
** All done...go home. Pass local pointer back.
*/
return(optrarray);
}
/**************
** stradjust **
***************
** Used by the string heap sort. Call this routine to adjust the
** string at offset i to length l. The members of the string array
** are moved accordingly and the length of the string at offset i
** is set to l.
*/
static void stradjust(farulong *optrarray, /* Offset pointer array */
faruchar *strarray, /* String array */
ulong nstrings, /* # of strings */
ulong i, /* Offset to adjust */
uchar l) /* New length */
{
unsigned long nbytes; /* # of bytes to move */
unsigned long j; /* Index */
int direction; /* Direction indicator */
unsigned char adjamount; /* Adjustment amount */
/*
** If new length is less than old length, the direction is
** down. If new length is greater than old length, the
** direction is up.
*/
direction=(int)l - (int)*(strarray+*(optrarray+i));
adjamount=(unsigned char)abs(direction);
/*
** See if the adjustment is being made to the last
** string in the string array. If so, we don't have to
** do anything more than adjust the length field.
*/
if(i==(nstrings-1L))
{ *(strarray+*(optrarray+i))=l;
return;
}
/*
** Calculate the total # of bytes in string array from
** location i+1 to end of array. Whether we're moving "up" or
** down, this is how many bytes we'll have to move.
*/
nbytes=*(optrarray+nstrings-1L) +
(unsigned long)*(strarray+*(optrarray+nstrings-1L)) + 1L -
*(optrarray+i+1L);
/*
** Calculate the source and the destination. Source is
** string position i+1. Destination is string position i+l
** (i+"ell"...don't confuse 1 and l).
** Hand this straight to memmove and let it handle the
** "overlap" problem.
*/
MoveMemory((farvoid *)(strarray+*(optrarray+i)+l+1),
(farvoid *)(strarray+*(optrarray+i+1)),
(unsigned long)nbytes);
/*
** We have to adjust the offset pointer array.
** This covers string i+1 to numstrings-1.
*/
for(j=i+1;j<nstrings;j++)
if(direction<0)
*(optrarray+j)=*(optrarray+j)-adjamount;
else
*(optrarray+j)=*(optrarray+j)+adjamount;
/*
** Store the new length and go home.
*/
*(strarray+*(optrarray+i))=l;
return;
}
/****************
** strheapsort **
*****************
** Pass this routine a pointer to an array of unsigned char.
** The array is presumed to hold strings occupying at most
** 80 bytes (counts a byte count).
** This routine also needs a pointer to an array of offsets
** which represent string locations in the array, and
** an unsigned long indicating the number of strings
** in the array.
*/
static void StrHeapSort(farulong *optrarray, /* Offset pointers */
faruchar *strarray, /* Strings array */
ulong numstrings, /* # of strings in array */
ulong bottom, /* Region to sort...bottom */
ulong top) /* Region to sort...top */
{
unsigned char temp[80]; /* Used to exchange elements */
unsigned char tlen; /* Temp to hold length */
unsigned long i; /* Loop index */
/*
** Build a heap in the array
*/
for(i=(top/2L); i>0; --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<j)
if(str_is_less(optrarray,strarray,numstrings,k,k+1L))
++k;
if(str_is_less(optrarray,strarray,numstrings,i,k))
{
/* temp=string[k] */
tlen=*(strarray+*(optrarray+k));
MoveMemory((farvoid *)&temp[0],
(farvoid *)(strarray+*(optrarray+k)),
(unsigned long)(tlen+1));
/* string[k]=string[i] */
tlen=*(strarray+*(optrarray+i));
stradjust(optrarray,strarray,numstrings,k,tlen);
MoveMemory((farvoid *)(strarray+*(optrarray+k)),
(farvoid *)(strarray+*(optrarray+i)),
(unsigned long)(tlen+1));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?