/* #include #include #include #include */ #include #include "nmglobal.h" #include "nbench1.h" /************************* ** 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 */ double *abase; /* Base of A[] coefficients array */ double *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=(double *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), &systemerror); if(systemerror) { ReportError(errorcontext,systemerror); ErrorExit(); } bbase=(double *)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((void *)abase,&systemerror); FreeMemory((void *)bbase,&systemerror); locfourierstruct->arraysize+=50L; } } else { /* ** Don't need self-adjustment. Just allocate the ** arrays, and go. */ abase=(double *)AllocateMemory(locfourierstruct->arraysize*sizeof(double), &systemerror); if(systemerror) { ReportError(errorcontext,systemerror); ErrorExit(); } bbase=(double *)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((void *)abase,&systemerror); FreeMemory((void *)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 unsigned long DoFPUTransIteration(double *abase, /* A coeffs. */ double *bbase, /* B coeffs. */ unsigned long 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