Files
csapp2025/malloclab/clock.c
2025-05-21 14:41:01 +08:00

108 lines
2.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#include <intrin.h>
#else
#include <unistd.h>
#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);
}