#include #include #include #include #include #include #include "nmglobal.h" #include "nbench1.h" #include "emfloat.h" /***************************** ** FLOATING-POINT EMULATION ** *****************************/ /************** ** DoEmFloat ** *************** ** Perform the floating-point emulation routines portion of the ** CPU benchmark. Returns the operations per second. */ void DoEmFloat(void) { /* Error context string pointer */ const char *errorcontext = "CPU:Floating Emulation"; /* Local structure */ EmFloatStruct *locemfloatstruct = &global_emfloatstruct; InternalFPF *abase = NULL; /* Base of A array */ InternalFPF *bbase = NULL; /* Base of B array */ InternalFPF *cbase = NULL; /* Base of C array */ unsigned long accumtime; /* Accumulated time in ticks */ double iterations; /* # of iterations */ unsigned long tickcount; /* # of ticks */ unsigned long loops; /* # of loops */ 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, cbase, locemfloatstruct->arraysize); /* FIXME: ugly */ /* 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, /* FIXME: ugly */ locemfloatstruct->arraysize, loops); if (tickcount > 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. */ accumtime = 0L; iterations = 0.0; do { accumtime += DoEmFloatIteration(abase, bbase, cbase, /* FIXME: ugly */ locemfloatstruct->arraysize, locemfloatstruct->loops); iterations += 1.0; } while (TicksToSecs(accumtime) < locemfloatstruct->request_secs); /* ** Clean up, calculate results, and go home. ** Also, indicate that adjustment is done. */ free(abase); free(bbase); free(cbase); locemfloatstruct->emflops = (iterations * (double)locemfloatstruct->loops) / (double)TicksToFracSecs(accumtime); if (locemfloatstruct->adjust == 0) { locemfloatstruct->adjust = 1; } }