#include #include #include #include #include #include #include "nmglobal.h" #include "nbench1.h" /************************ ** BITFIELD OPERATIONS ** *************************/ static unsigned long DoBitfieldIteration(unsigned long *bitarraybase, unsigned long *bitoparraybase, long bitoparraysize, unsigned long *nbitops); static void ToggleBitRun(unsigned long *bitmap, unsigned long bit_addr, unsigned long nbits, unsigned int val); static void FlipBitRun(unsigned long *bitmap, unsigned long bit_addr, unsigned long nbits); /************* ** DoBitops ** ************** ** Perform the bit operations test portion of the CPU ** benchmark. Returns the iterations per second. */ void DoBitops(void) { /* Error context string */ const char *context = "CPU:Bitfields"; /* Local bitop structure */ BitOpStruct *locbitopstruct = &global_bitopstruct; unsigned long *bitarraybase = NULL; /* Base of bitmap array */ unsigned long *bitoparraybase = NULL; /* Base of bitmap operations array */ unsigned long nbitops; /* # of bitfield operations */ unsigned long accumtime; /* Accumulated time in ticks */ double iterations; /* # of iterations */ int ticks; /* ** See if we need to run adjustment code. */ if (locbitopstruct->adjust == 0) { bitarraybase = realloc(bitarraybase, locbitopstruct->bitfieldarraysize * sizeof(unsigned long)); if (!bitarraybase) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); exit(1); } /* ** Initialize bitfield operations array to [2,30] elements */ locbitopstruct->bitoparraysize = 30L; while(1) { bitoparraybase = malloc(locbitopstruct->bitoparraysize * 2 * sizeof(unsigned long)); if (!bitoparraybase) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); free(bitarraybase); exit(1); } /* ** 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. */ ticks = DoBitfieldIteration(bitarraybase, bitoparraybase, locbitopstruct->bitoparraysize, &nbitops); if (ticks > global_min_ticks) { break; } locbitopstruct->bitoparraysize += 100L; } } else { /* ** Don't need to do self adjustment, just allocate ** the array space. */ bitarraybase = malloc(locbitopstruct->bitfieldarraysize * sizeof(unsigned long)); if (!bitarraybase) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); exit(1); } bitoparraybase = malloc(locbitopstruct->bitoparraysize * 2 * sizeof(unsigned long)); if (!bitoparraybase) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); free(bitarraybase); exit(1); } } /* ** All's well if we get here. Repeatedly perform bitops until the ** accumulated elapsed time is greater than # of seconds requested. */ accumtime = 0L; iterations = 0.0; do { accumtime += DoBitfieldIteration(bitarraybase, bitoparraybase, locbitopstruct->bitoparraysize,&nbitops); iterations += (double)nbitops; } 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. */ free(bitarraybase); free(bitoparraybase); locbitopstruct->bitopspersec = iterations / TicksToFracSecs(accumtime); if (locbitopstruct->adjust == 0) { locbitopstruct->adjust = 1; } } /************************ ** DoBitfieldIteration ** ************************* ** Perform a single iteration of the bitfield benchmark. ** Return the # of ticks accumulated by the operation. */ static unsigned long DoBitfieldIteration(unsigned long *bitarraybase, unsigned long *bitoparraybase, long bitoparraysize, unsigned long *nbitops) { long i; /* Index */ unsigned long bitoffset; /* Offset into bitmap */ unsigned long 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) */ /* ** Reset random number generator so things repeat. ** Also reset the bit array we work on. ** added by Uwe F. Mayer */ randnum((int32_t)13); for (i=0;i>6; /* Index is number /64 */ bitnumb=bit_addr % 64; /* 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<> 6; /* Index is number /64 */ bitnumb = bit_addr % 64; /* Bit number in word */ if (val) { bitmap[bindex] |= (1L << bitnumb); } else { bitmap[bindex] &= ~(1L << bitnumb); } bit_addr++; } #else if (val) { for (; nbits != 0; nbits--) { bindex = bit_addr >> 6; bitnumb = bit_addr % 64; bitmap[bindex] |= (1L << bitnumb); bit_addr++; } } else { for (; nbits != 0; nbits--) { bindex = bit_addr >> 6; bitnumb = bit_addr % 64; bitmap[bindex] &= ~(1L << bitnumb); bit_addr++; } } #endif return; }