This does not happen in my E8200, but on my Atom N450 netbook (both work with OpenSuse 11.2), whenever I read the CPU TSC, the return value is mod 10 == 0 , i. E. It is divisible by 10. I use the RDTSC value to measure the time it takes for interesting code fragments, but for demonstration I made this small program:
.text .global _start _start: xorl %ebx,%ebx xorl %ecx,%ecx xorl %r14d,%r14d movb $10,%cl loop: xchgq %rcx,%r15
(I usually use my own procedures for converting, but in order not to suggest to the readers that the error may be there, I just use printf () here.)
With the above code, the output (for example):
rdtsc: 0x000b88ef933ffd06 = 3246787292822790 -- delta: 3246787292822790 rdtsc: 0x000b88ef9342fcf4 = 3246787293019380 -- delta: 196590 rdtsc: 0x000b88ef93435dca = 3246787293044170 -- delta: 24790 rdtsc: 0x000b88ef9343b43c = 3246787293066300 -- delta: 22130 rdtsc: 0x000b88ef93440c34 = 3246787293088820 -- delta: 22520 rdtsc: 0x000b88ef9344604e = 3246787293110350 -- delta: 21530 rdtsc: 0x000b88ef9344b4d6 = 3246787293131990 -- delta: 21640 rdtsc: 0x000b88ef9345085a = 3246787293153370 -- delta: 21380 rdtsc: 0x000b88ef93455d96 = 3246787293175190 -- delta: 21820 rdtsc: 0x000b88ef9345b16a = 3246787293196650 -- delta: 21460
As you can see, the delta varies in reasonable quantities. But noticeable (not to mention collusion ;-) is that the least significant decimal digit is always 0.
I have been observing this phenomenon for more than two years, and Qaru is not the first address where I post this problem. But I havenโt received a reasonable answer anywhere. The ideas that we (I and other people there) came up with are that
- TSC only increases every 10 th but then by 10 or
- The TSC is internally updated correctly, but only externally reflected every 10 th or
- TSC is increased by 10 per cycle.
However, none of these points make sense. I had to run such a program on the E8200 (which is currently out of order) to determine if the delta order is the same, or only one tenth of the above outputs. (Any volunteers?)
Googling did not help; Intel executives did neither.
When discussing with other people, there was no one to experience the same behavior. If this is due to the kernel, then at least 3 versions have suffered, but then ... what is the kernel related to?
I also had a maintenance netbook, and it came back with a new motherboard - implied a new processor, so at least two separate N450 objects must be touched.
I also took measures against changing the clock frequency (and no matter what frequency I fixed the clock on, the values โโchanged only in the expected range (the same as shown)) and turned off the HT, although they should actually help to get some least significant numbers, not prevent them. But to be sure.
Well, if someone wants to run the program on their machine, then on the command line (if you save the source file in the rdtsc.s file):
as rdtsc.s -o rdtsc.o ld --dynamic-linker=/lib64/ld-linux-x86-64.so.2 rdtsc.o -L /lib64 -lc -o rdtsc
To build it with gcc, i. e.
gcc -lc rdtsc.s -o rdtsc
you must add (or replace the _start: label with the main: label and make it global.
[update (2012-09-15 ~ 21:15 UTC): Actually, I could have done this earlier: I just enable TSC before and after sleep(1) , which gives the delta a little more than 1,666,000,000, which shows that the third point in the list above is incorrect. But still I have no idea why I am not getting full accuracy. / Update]