nbench1.c

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

C
2,217
字号

                /* string[i]=temp */
                tlen=temp[0];
                stradjust(optrarray,strarray,numstrings,i,tlen);
                MoveMemory((farvoid *)(strarray+*(optrarray+i)),
                        (farvoid *)&temp[0],
                        (unsigned long)(tlen+1));
                i=k;
        }
        else
                i=j+1;
}
return;
}

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

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

do {
        accumtime+=DoBitfieldIteration(bitarraybase,
                        bitoparraybase,
                        locbitopstruct->bitoparraysize,&nbitops, &wat_time);
        iterations+=(double)nbitops;
	tot_time += wat_time;
} while(TicksToSecs(accumtime)<locbitopstruct->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);
tot_time /= iterations;
ReportTime( tot_time );
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, double *wat_time)
{
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<bitoparraysize;i++)
{
        /* First item is offset */
        *(bitoparraybase+i+i)=bitoffset=abs_randwc(262140L);

        /* Next item is run length */
        *nbitops+=*(bitoparraybase+i+i+1L)=abs_randwc(262140L-bitoffset);
}

/*
** Array of offset and lengths built...do an iteration of
** the test.
** Start the stopwatch.
*/
elapsed=StartStopwatch();
TimerOn();

/*
** Loop through array off offset/run length pairs.
** Execute operation based on modulus of index.
*/
for(i=0;i<bitoparraysize;i++)
{
        switch(i % 3)
        {

                case 0: /* Set run of bits */
                        ToggleBitRun(bitarraybase,
                                *(bitoparraybase+i+i),
                                *(bitoparraybase+i+i+1),
                                1);
                        break;

                case 1: /* Clear run of bits */
                        ToggleBitRun(bitarraybase,
                                *(bitoparraybase+i+i),
                                *(bitoparraybase+i+i+1),
                                0);
                        break;

                case 2: /* Complement run of bits */
                        FlipBitRun(bitarraybase,
                                *(bitoparraybase+i+i),
                                *(bitoparraybase+i+i+1));
                        break;
        }
}

/*
** Return elapsed time
*/
TimerOff();
elapsed = StopStopwatch(elapsed);
if( wat_time ) {
    *wat_time = TimerElapsed();
}
return(elapsed);
}


/*****************************
**     ToggleBitRun          *
******************************
** Set or clear a run of nbits starting at
** bit_addr in bitmap.
*/
static void ToggleBitRun(farulong *bitmap, /* Bitmap */
                ulong bit_addr,         /* Address of bits to set */
                ulong nbits,            /* # of bits to set/clr */
                uint val)               /* 1 or 0 */
{
unsigned long bindex;   /* Index into array */
unsigned long bitnumb;  /* Bit number */

while(nbits--)
{
#ifdef LONG64
        bindex=bit_addr>>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<<bitnumb);
        else
                bitmap[bindex]&=~(1L<<bitnumb);
        bit_addr++;
}
return;
}

/***************
** FlipBitRun **
****************
** Complements a run of bits.
*/
static void FlipBitRun(farulong *bitmap,        /* Bit map */
                ulong bit_addr,                 /* Bit address */
                ulong nbits)                    /* # of bits to flip */
{
unsigned long bindex;   /* Index into array */
unsigned long bitnumb;  /* Bit number */

while(nbits--)
{
#ifdef LONG64
        bindex=bit_addr>>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<<bitnumb);
        bit_addr++;
}

return;
}

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

/*
** 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;loops<CPUEMFLOATLOOPMAX;loops+=loops)
        {       tickcount=DoEmFloatIteration(abase,bbase,cbase,
                        locemfloatstruct->arraysize,
                        loops, NULL);
                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;
tot_time=(double)0.0;
do {
        accumtime+=DoEmFloatIteration(abase,bbase,cbase,
                        locemfloatstruct->arraysize,
                        locemfloatstruct->loops, &wat_time);
        iterations+=(double)1.0;
	tot_time += wat_time;
} while(TicksToSecs(accumtime)<locemfloatstruct->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);
tot_time /= ((double)(locemfloatstruct->loops) * iterations);
ReportTime( tot_time );

if(locemfloatstruct->adjust==0)
        locemfloatstruct->adjust=1;

return;
}

/*************************
** FOURIER COEFFICIENTS **
*************************/

/**************

⌨️ 快捷键说明

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