Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Time calculation with TSC (Time Stamp Counter)

I am trying to measure the time taken by some code inside Linux kernel at very high accuracy by a Linux kernel module.

For this purpose, I have tried rdtscl() which gives the number of clock ticks used in the code as given below:

unsigned long ini, end;
rdtscl(ini);
//some code...
rdtscl(end);
printk("time taken=%lu ticks",end-ini);

As I have refered to http://en.wikipedia.org/wiki/Time_Stamp_Counter which says that TSC is a 64-bit register present on all x86 processors since the Pentium. So, if I have dual core processor, will this counter be present in both cores or there will be only one since it is only one processor but dual core?

The second question is that: I have Intel Xeon i3 processor which has 4 processors, each of them having 2 cores. Then, measuring the clock ticks, will give the ticks of single processor or addition of all 4 processors?

like image 777
akp Avatar asked Dec 24 '12 06:12

akp


People also ask

What is TSC in kernel?

This is a counter implemented in every x86 microprocessor by means of a 64-bit register called TSC the register. It counts the number of clock signals arriving on the CLK pin of the processor. The current counter value can be read by accessing the TSC register.

What is TSC in CPU?

This is a high-resolution counter inside the CPU which counts CPU cycles. This counter is called Timer Stamp Counter (TSC) on x86/Intel®64 architectures. It can be read through an assembler instruction, so the overhead is much lower than gettimeofday().

What is TSC clock source?

Reading Hardware Clock Sources. Reading from the TSC means reading a register from the processor. Reading from the HPET clock means reading a memory area. Reading from the TSC is faster, which provides a significant performance advantage when timestamping hundreds of thousands of messages per second.

What is RDTSC instruction?

The rdtsc (Read Time-Stamp Counter) instruction is used to determine how many CPU ticks took place since the processor was reset. Loads the current value of the processor's time-stamp counter into the EDX:EAX registers. It is commonly used as a timing defense (anti-debugging technique).


2 Answers

If you get NO clock ticks, then there's something seriously wrong with your code. Did you write your own rdtscl [or copy it from somewhere that isn't a good source?]

By the way, modern Intel (and AMD) processors may well have "constant TSC", so a processor that is halted, sleeping, running slower, etc, will still tick away at the same rate as the others - it may not be in sync still, but that's a different matter.

Try running just a loop that prints the value from your counter - just the RDTSC instruction itself should take some 30-50 clock cycles, so you should see it moving.

Edit: Here's my rdtsc function:

void rdtscl(unsigned long long *ll)
{
    unsigned int lo, hi;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));                        
    *ll = ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );  
}

alernatitvely, as a function returning a value:

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

I notice that your code doesn't pass a pointer of your unsigned long, which makes me suspect that you are not actually passing the timestamp counter BACK to the caller, but rather just keeping whatever value it happens to have - which may well be the same for both values.

like image 54
Mats Petersson Avatar answered Oct 01 '22 21:10

Mats Petersson


All the cores have their own TSC; it basically counts cycles- but beware - the TSC clocks may not be synchronized! if your code starts running on one core and migrates to the 2nd one, which is certainly possible in the general case, your count will be wrong!

like image 23
gby Avatar answered Oct 01 '22 19:10

gby