#include #include #include #include #include #include #include #include #include "cleanbench.h" #include "randnum.h" #include "emfloat.h" /***************************** ** FLOATING-POINT EMULATION ** *****************************/ /* ** The following constant is the maximum number of loops ** of the emulated floating point test that the system ** will allow before flagging an error. This is not a ** critical constant, and can be altered if your system is ** a real barn-burner. */ #define LOOP_MAX 500000L #define ARRAY_SIZE 3000 static clock_t DoEmFloatIteration(InternalFPF *abase, InternalFPF *bbase, InternalFPF *cbase, unsigned long loops); static void SetupCPUEmFloatArrays(InternalFPF *abase, InternalFPF *bbase); /************** ** DoEmFloat ** *************** ** Perform the floating-point emulation routines portion of the ** CPU benchmark. Returns the operations per second. */ double DoEmFloat(void) { InternalFPF* abase = NULL; InternalFPF* bbase = NULL; InternalFPF* cbase = NULL; clock_t total_time = 0; int iterations = 0; static bool is_adjusted = false; static long loops = 1; abase = malloc(ARRAY_SIZE * sizeof(InternalFPF)); bbase = malloc(ARRAY_SIZE * sizeof(InternalFPF)); cbase = malloc(ARRAY_SIZE * sizeof(InternalFPF)); SetupCPUEmFloatArrays(abase, bbase); /* FIXME: ugly */ /* See if we need to do self-adjusting code.*/ if (is_adjusted == false) { is_adjusted = true; /* ** Do an iteration of the tests. If the elapsed time is ** less than minimum, increase the loop count and try ** again. */ do { loops += loops; } while ((DoEmFloatIteration(abase, bbase, cbase, loops) <= MINIMUM_TICKS) && (loops < LOOP_MAX)); } /* ** Verify that selft adjustment code worked. */ if (loops == 0) { fputs("CPU:EMFPU -- CMPUEMFLOATLOOPMAX limit hit", stderr); free(abase); free(bbase); free(cbase); exit(1); } /* ** 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 ARRAY_SIZE * 3 operations. */ do { total_time += DoEmFloatIteration(abase, bbase, cbase, loops); ++iterations; } while (total_time < MINIMUM_SECONDS * CLOCKS_PER_SEC); free(abase); free(bbase); free(cbase); return (double)(iterations * loops * CLOCKS_PER_SEC) / (double)total_time; } /*********************** ** DoEmFloatIteration ** ************************ ** Perform an iteration of the emulated floating-point ** benchmark. Note that "an iteration" can involve multiple ** loops through the benchmark. */ static clock_t DoEmFloatIteration(InternalFPF *abase, InternalFPF *bbase, InternalFPF *cbase, unsigned long loops) { clock_t start, stop; static unsigned char jtable[16] = {0,0,0,0,1,1,1,1,2,2,2,2,2,3,3,3}; unsigned long i; start = clock(); /* ** Each pass through the array performs operations in ** the followingratios: ** 4 adds, 4 subtracts, 5 multiplies, 3 divides ** (adds and subtracts being nearly the same operation) */ while(loops--) { for(i=0;i