2012-06-26 90 views
2

更新clock_gettime不能立即

更新檢查的時間分辨率後,我們試圖調試內核空間的問題。

unsigned long long task_sched_runtime(struct task_struct *p) 
{ 
    unsigned long flags; 
    struct rq *rq; 
    u64 ns = 0; 

    rq = task_rq_lock(p, &flags); 
    ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq); 
    task_rq_unlock(rq, &flags); 

    //printk("task_sched runtime\n"); 
    return ns; 
} 

我們的新實驗表明時間p->se.sum_exec_runtime沒有立即更新。但是如果我們在函數內部添加printk()。時間會立即更新。

我們正在開發Android程序。 但是,功能threadCpuTimenanos()測量的時間在我們的平臺上並不總是正確的。

實驗結束後,我們發現從clock_gettime返回的時間沒有立即更新。 即使經過幾次while循環迭代,我們得到的時間仍然不會改變。

下面是我們的示例代碼:

​​

此代碼運行在x86 PC上的好。但是,在我們的內核2.6.35.13的嵌入式平臺ARM Cortex-A9中,它無法正確運行。

任何想法?

+0

也許計數器只能精確到毫秒?這個循環幾乎不消耗CPU,因此需要多輪才能達到1ms。你是否試圖用忙碌的等待來取代睡眠? – ugoren

+1

你想測量什麼?通過「掛鐘時間」的時間或程序佔用CPU的時間? –

+0

是的,睡眠是不必要的。我們想稍後再衡量一次。時間程序佔用CPU。 – user1247081

回答

1

clock_gettime的分辨率取決於平臺。使用clock_getres()在您的平臺上查找分辨率。根據您的實驗結果,pc-x86上和您的目標平臺上的時鐘分辨率是不同的。

+0

感謝您的回覆。 但我們發現時間分辨率與x86相同。 – user1247081

0

CLOCK_THREAD_CPUTIME_ID時鐘用於衡量CPU花費的時間,而不是實時時間,並且您花費的CPU時間幾乎爲零。此外,CLOCK_THREAD_CPUTIME_ID(線程特定的CPU時間)在Linux/glibc上執行不正確,甚至在glibc上可能完全無法工作。 CLOCK_PROCESS_CPUTIME_ID或其他所謂的應該更好地工作。

+0

是的,CPU在線程中消耗的時間幾乎爲零。但是,即使我們帶走了睡眠。結果仍然是一樣的。並嘗試CLOCK_PROCESS_CPUTIME_ID仍然沒有工作。 – user1247081

1

在android CTS中,有一個案例有相同的問題。讀定時器兩次,但它們是相同的

testThreadCpuTimeNanos在 android.os.cts.DebugTest.testThreadCpuTimeNanos失敗junit.framework.AssertionFailedError

1

$男人clock_gettime

...

SMP系統的注意事項

CLOCK_PROCESS_CPUTIME_ID和CLOCK_THREAD_CPUTIME_ID時鐘在許多平臺上實現使用來自CPU的定時器(i386上的TSC,Itanium上的AR.ITC)。這些寄存器在CPU之間可能會有所不同,因此如果某個進程遷移到另一個CPU,這些時鐘可能會返回虛假結果

如果SMP系統中的CPU具有不同的時鐘源,則無法保持定時器寄存器之間的相關性,因爲每個CPU將以稍微不同的頻率運行。如果是這種情況,那麼clock_getcpuclockid(0)將返回ENOENT來表示這種情況。如果可以確保某個進程停留在某個CPU上,那麼這兩個時鐘纔會有用。

在SMP系統中的處理器不在完全相同的時間啓動所有因此定時器寄存器在偏移通常是運行。一些體系結構包括試圖在啓動時限制這些偏移量的代碼。但是,代碼無法保證準確調整偏移量。 Glibc不包含處理這些偏移的規定(與Linux內核不同)。通常這些偏移量很小,因此在大多數情況下效果可能可以忽略不計。

2

我改變了clock_gettime使用CLOCK_MONOTONIC_RAW,分配給一個CPU的線程,我得到不同的值。 我也在使用雙皮質A9

while(1) 
{ 
    test = 1; 
    test = clock_gettime(CLOCK_MONOTONIC_RAW, &now); 

    printf(" clock gettime test 1 %lx, %lx , ret = %d\n",now.tv_sec , now.tv_nsec, test); 

    pre = now.tv_nsec; 
    sleep(1); 
} 
+1

在clock_gettimes和clock_gettimes之間有一個很大的printf,連續調用clock_gettime,你會發現有時你會得到零的差異,如果分辨率低至1ns,這並沒有什麼意義。 – auselen