0

Below is code my testing my computer's CPU frequency and timing a function using rdtsc.

/* Code only works on x86 machine compiling with GCC */

/* Keep track of most recent reading of cycle counter */
static unsigned cyc_hi = 0;
static unsigned cyc_lo = 0;

void access_counter(unsigned *hi, unsigned *lo)
{
  /* Get cycle counter */
  asm("rdtsc; movl %%edx,%0; movl %%eax,%1" 
      : "=r" (*hi), "=r" (*lo)
      : /* No input */ 
      : "%edx", "%eax");
}

double get_counter()
{
  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;
  return (double) hi * (1 << 30) * 4 + lo;
}

void start_counter()
{
  access_counter(&cyc_hi, &cyc_lo);
}

void p()
{
  sleep(1);
}

int main(int argc, char const *argv[])
{
    /* Determine Clock Rate of Processor */
    double MHZ;
    int sleep_time = 10;
    start_counter();
    sleep(sleep_time);
    MHZ = get_counter() / (sleep_time * 1e6);
    printf("Processor Clock Rate ~= %.1f MHz\n", MHZ);
    /* cat /proc/cpuinfo */

    /* Time Function P */
    double tsecs;
    start_counter();
    p();
    tsecs = get_counter() / (MHZ * 1e6);
  printf("%.1f seconds\n", tsecs);
    return 0;
}

After running this program, it prints the processor clock rate is around 3591.8MHz, then I run cat /proc/cpuinfo, it shows there are 8 processors (0 ~7), and some processors' cpu MHz are different, but no one is 3591.8Mhz. I am wondering how do I interpret this value, 3591.8MHz? Many thanks.

HuangJie
  • 1,488
  • 1
  • 16
  • 33
  • Which values are you getting? – Eugene Sh. Jul 11 '16 at 15:52
  • Try using [cpufreq-info](http://linux.die.net/man/1/cpufreq-info) and [cpufreq-set](http://linux.die.net/man/1/cpufreq-set) to set the CPU frequency or governor and then run your program. – s7amuser Jul 11 '16 at 15:57

2 Answers2

1

CPU can reclock thousands of time per second. They are designed to do that. Likely your program works correctly and shows a snapshot of a current frequency which is not observed when you manually do the cat after? Also your program creates some workload so it will likely spike one CPU to momentary come out of some deep hybernation state to quickly do the work and then go back to sleep. This is behaviour of new intel core i processors. What is your CPU? If you do cat /proc/cpuinfo multiple times do you get the same results?

XapaJIaMnu
  • 1,408
  • 3
  • 12
  • 28
  • Thanks for your reply. My cpu is Intel(R) Core(TM) i7-4790. Yes, I run cat after the program is finished. So that's why I cannot see the print value of the program in cpuinfo? – HuangJie Jul 11 '16 at 16:04
  • I believe so. This is a Haswell that with many power saving states and very aggressive power saving logic. Did you `cat /proc/cpuinfo` multiple times? Did you get the same results? – XapaJIaMnu Jul 11 '16 at 16:24
  • Thanks for your reply. I cat /proc/cpuinfo many times to see the current active CPU frequency while the program is running. Although I did not see exact 3591.8Mhz which the program prints out, but cat /proc/cpuinfo is very near to this number. – HuangJie Jul 11 '16 at 16:32
0

If you use /proc/cpuinfo, the bogomips field is stable and is 2x the CPU frequency.

If you have a recent processor, it will have a fixed [maximum] clock rate for TSC, which is denoted by constant_tsc in the flags field in /proc/cpuinfo. That means it will not vary, even if the processor has speed step.

So, what you want is the maximum CPU frequency, which you can get by reading:

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

See my answer here for more details: Getting TSC rate in x86 kernel

Community
  • 1
  • 1
Craig Estey
  • 30,627
  • 4
  • 24
  • 48