2012-12-24 114 views
2

我試圖通過Linux內核模塊以非常高的準確度測量Linux內核中的一些代碼所用的時間。使用TSC(時間戳計數器)計算時間

爲此,我試圖rdtscl()其給出時鐘滴答數代碼中使用如下面給出的:

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

正如我refered到http://en.wikipedia.org/wiki/Time_Stamp_Counter它說,TSC是自Pentium以來,所有x86處理器上均存在64位寄存器。所以,如果我有雙核心處理器,這個計數器會出現在兩個核心中,還是隻有一個,因爲它只有一個處理器,但是雙核心?

第二個問題是:我有英特爾至強i3處理器,它有4個處理器,每個處理器有2個內核。然後,測量時鐘滴答,將給出單個處理器的滴答聲或添加所有4個處理器?

+0

時鐘滴答與運行'rdtscl'的核心相關 –

回答

1

所有內核都有自己的TSC;它基本上是對週期進行計數 - 但要注意 - TSC時鐘可能不同步!如果你的代碼開始在一個核心上運行並遷移到第二個核心,這在一般情況下肯定是可行的,那麼你的計數將是錯誤的!

2

同樣WikiPedia文章並說,大約與TSC如下問題,

With the advent of multi-core/hyper-threaded CPUs, systems with multiple CPUs, and 
hibernating operating systems, the TSC cannot be relied on to provide accurate results 
— unless great care is taken to correct the possible flaws: rate of tick and whether 
all cores (processors) have identical values in their time-keeping registers. **There 
is no promise that the timestamp counters of multiple CPUs on a single motherboard will 
be synchronized**. In such cases, programmers can only get reliable results by locking 
their code to a single CPU. Even then, the CPU speed may change due to power-saving 
measures taken by the OS or BIOS, or the system may be hibernated and later resumed 
(resetting the time stamp counter). In those latter cases, to stay relevant, the 
counter must be recalibrated periodically (according to the time resolution your 
application requires). 

含義現代的CPU可以改變他們的CPU時鐘頻率,以節省功耗可影響TSC的值。在內核可以執行HALT並停止處理器直到收到外部中斷的情況下,TSC也不會增加。

the second question is that i have intel xeon i3 processor which has 4 processors & 
each having 2 cores then measuring the clock ticks will give the ticks of single 
processor or addition of all 4 processors..? 

這可能導致一種情況的處理可以在一個處理器讀出的時間,將移動到一個第二處理器和遇到的時間早於它,這導致TSC爲不穩定時所述第一處理器上讀取的一個資源。

3

如果你沒有時鐘滴答,那麼你的代碼有一些嚴重錯誤。現在的英特爾(和AMD)處理器可能會有「恆定的TSC」,所以一個停止處理的處理器,睡覺,跑得慢等等,仍然會以與其他人相同的速度跳動 - 它可能不會同步,但這是另一回事。

嘗試運行一個只打印計數器值的循環 - 只需RDTSC指令本身需要30-50個時鐘週期,所以您應該看到它正在移動。

編輯:這是我的RDTSC功能:

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,爲返回值的函數:

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); 
} 

我注意到,您的代碼不通過你的unsigned long類型的指針,這讓我懷疑你實際上並沒有將時間戳記計數器傳遞給調用者,而只是保留它發生的任何值 - 這對兩個值都可能是相同的。

+0

什麼是lo和hi在這裏? –

+0

固定,他們是32位整數。 –

0

這裏提到的一些事情是準確的,因爲TSC不是時間的量度,因爲CPU中的S狀態。但我認爲即使在多核環境下,TSC也可用於相對測序。有一個稱爲TSCInvariant的標誌,在Intel CPU> = nehalem arch中設置爲true。在這些CPU中,TSC在所有內核上以恆定速率變化。因此,如果將上下文切換到不同的核心,您將永遠不會回到TSC計數中。

在Ubuntu中,你可以做命令和apt-get安裝CPUID

CPUID | grep TscInvariant在您的桌面上驗證它。