TSC Register

From Tuxamito
Revision as of 14:43, 7 November 2014 by Daniel (talk | contribs)
Jump to: navigation, search

The Time Stamp Counter (TSC) is a 64-bit register present in most modern x86 processors.

It counts the number of cycles since reset.

The instruction RDTSC returns the TSC in EDX:EAX

supported out-of-order execution

not necessarily performed in the order they appear in the executable

This can cause RDTSC to be executed later or earlier -> misleading cycle count.

using the RDTSCP instruction, which is a serializing variant of the RDTSC instruction. -> force every preceding instruction to complete

the time-stamp counter increments at a constant rate. That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may differ from the maximum qualified frequency of the processor.

Since the family 10h (Barcelona/Phenom), AMD chips feature a constant TSC.


From Nehalem

By default the TSC is synchronized across all cores. However, the TSC value of a core could be changed by some software subsystem using the WRMSR instruction. Take a look at quotes below and I hope they finally answer your question:

Intel(R) 64 and IA-32 Architectures Software Developer’s Manual Volume 3 (3A, 3B & 3C): System Programming Guide


Need to use "volatile" variables so that the compiler does not change the order.

typedef unsigned long long Tsc_t;

inline Tsc_t readTsc(void)
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#include <stdio.h>

typedef unsigned long long Tsc_t;

inline Tsc_t readTsc(void)
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}


int main(void) {
  Tsc_t t1;
  Tsc_t t2;

  t1 = readTsc();
  t2 = readTsc();

  printf("%llu\n", (t2-t1));

  return 0;
}
#include <stdio.h>
#include <unistd.h>

typedef unsigned long long Tsc_t;

inline Tsc_t readTsc(void)
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}


int main(void) {
  Tsc_t t1;
  Tsc_t t2;

  t1 = readTsc();
  sleep(1);
  t2 = readTsc();

  printf("%llu\n", (t2-t1));

  return 0;
}