#include #include #include #ifdef _WIN32 #include #include #else #include #endif #include "clock.h" void start_counter(void); double get_counter(void); /* * Routines for using the cycle counter */ /* $begin x86cyclecounter */ /* Initialize the cycle counter */ static unsigned cyc_hi = 0; static unsigned cyc_lo = 0; /* Set *hi and *lo to the high and low order bits of the cycle counter. Implementation requires assembly code to use the rdtsc instruction. */ void access_counter(unsigned* hi, unsigned* lo) { #ifdef _WIN32 long long counter; counter = __rdtsc(); (*hi) = (unsigned int)(counter >> 32); (*lo) = (unsigned int)counter; #else asm("rdtsc; movl %%edx,%0; movl %%eax,%1" /* Read cycle counter */ : "=r" (*hi), "=r" (*lo) /* and move results to */ : /* No input */ /* the two outputs */ : "%edx", "%eax"); #endif } /* Record the current value of the cycle counter. */ void start_counter(void) { access_counter(&cyc_hi, &cyc_lo); } /* Return the number of cycles since the last call to start_counter. */ double get_counter(void) { unsigned ncyc_hi, ncyc_lo; unsigned hi, lo, borrow; double result; /* Get cycle counter */ access_counter(&ncyc_hi, &ncyc_lo); /* Do double precision subtraction */ lo = ncyc_lo - cyc_lo; borrow = lo > ncyc_lo; hi = ncyc_hi - cyc_hi - borrow; result = (double)hi * (1 << 30) * 4 + lo; if (result < 0) { printf("[%s]错误!counter返回了负值:%.0f\n", __func__, result); } return result; } void make_CPU_busy(void) { volatile double old_tick, new_tick; start_counter(); old_tick = get_counter(); new_tick = get_counter(); while (new_tick - old_tick < 1000000000) new_tick = get_counter(); } /* $begin mhz */ /* Estimate the clock rate by measuring the cycles that elapse */ /* while sleeping for sleeptime seconds */ double mhz_full(int verbose, int sleeptime) { double rate; if (verbose) printf("[%s]准备开始测量处理器性能,睡眠时间=%d秒\n", __func__, sleeptime); start_counter(); #ifdef _WIN32 Sleep(sleeptime * 1000); #else sleep(sleeptime); #endif rate = get_counter() / (1e6 * sleeptime); if (verbose) printf("[%s]处理器主频 ~= %.1f MHz\n", __func__, rate); return rate; } /* $end mhz */ /* Version using a default sleeptime */ double mhz(int verbose) { return mhz_full(verbose, 2); }