#include #include #include #include #include #include #include #include "nmglobal.h" #include "randnum.h" #include "emfloat.h" /***************************** ** FLOATING-POINT EMULATION ** *****************************/ static clock_t DoEmFloatIteration(InternalFPF *abase, InternalFPF *bbase, InternalFPF *cbase, unsigned long arraysize, unsigned long loops); static void SetupCPUEmFloatArrays(InternalFPF *abase, InternalFPF *bbase, unsigned long arraysize); /************** ** DoEmFloat ** *************** ** Perform the floating-point emulation routines portion of the ** CPU benchmark. Returns the operations per second. */ void DoEmFloat(void) { const char* errorcontext = "CPU:Floating Emulation"; EmFloatStruct* locemfloatstruct = &global_emfloatstruct; InternalFPF* abase = NULL; InternalFPF* bbase = NULL; InternalFPF* cbase = NULL; clock_t total_time = 0; int iterations = 0; unsigned long loops = 1; abase = malloc(locemfloatstruct->arraysize * sizeof(InternalFPF)); if (!abase) { printf("ERROR CONDITION\nContext: %s\n", errorcontext); exit(1); } bbase = malloc(locemfloatstruct->arraysize * sizeof(InternalFPF)); if (!bbase) { printf("ERROR CONDITION\nContext: %s\n", errorcontext); free(abase); exit(1); } cbase = malloc(locemfloatstruct->arraysize * sizeof(InternalFPF)); if (!cbase) { printf("ERROR CONDITION\nContext: %s\n", errorcontext); free(abase); free(bbase); exit(1); } SetupCPUEmFloatArrays(abase, bbase, locemfloatstruct->arraysize); /* FIXME: ugly */ /* See if we need to do self-adjusting code.*/ if (locemfloatstruct->adjust == FALSE) { locemfloatstruct->adjust = TRUE; 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 < CPUEMFLOATLOOPMAX; loops += loops) { if (DoEmFloatIteration(abase, bbase, cbase, locemfloatstruct->arraysize, loops) > global_min_ticks) { locemfloatstruct->loops = loops; break; } } } /* ** Verify that selft adjustment code worked. */ if (locemfloatstruct->loops == 0) { puts("CPU:EMFPU -- CMPUEMFLOATLOOPMAX limit hit"); 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 arraysize * 3 operations. */ do { total_time += DoEmFloatIteration(abase, bbase, cbase, locemfloatstruct->arraysize, locemfloatstruct->loops); ++iterations; } while (total_time < locemfloatstruct->request_secs * CLOCKS_PER_SEC); free(abase); free(bbase); free(cbase); locemfloatstruct->emflops = (double)(iterations * locemfloatstruct->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 arraysize, 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