我正在使用Linux安全模塊鉤子爲recv()系統調用添加一些自定義功能。與原始recv()相比,我想測量此功能的開銷。我寫了一個簡單的tcp服務器,我運行並沒有我的模塊。這個tcp服務器調用一個recv()函數'N'次。它測量與像對各時間的recv:測量Linux內核中函數的執行時間
clock_gettime(before);
recv()
clock_gettime(after);
global_time += after - before.
最後,我打印的平均時間爲單個的recv()中包含「global_time/N」。這段時間稱爲「user_space_avg_recv」時間。
在我的模塊內部,我想要放置時間測量函數來計算我的鉤子的準確執行時間。我嘗試了3種方法。
我用的jiffies如下:
sj = jiffies; my_hook(); ej = jiffies; current->total_oh = ej - sj;
但我看到有SJ和EJ值之間沒有差別。因此total_oh不變。
我用current_kernel_time(),因爲我認爲它返回的時間以納秒爲單位。但是,再一次,前後沒有差別。
我用過get_cycles。當進程退出時,我會打印整個週期。不過,當我將總週期值轉換爲毫秒時,它會比「user_space_avg_recv」值大得多。這是沒有意義的,因爲內核中的測量值總是小於從用戶空間測量的時間值。這可能意味着我要麼不使用正確的API進行測量,要麼在將數值從週期轉換爲毫秒時出錯。
我基本上是用下面的公式週期轉換成毫秒:
avg overhead of my hook in milliseconds =
(((cycles/2.99)/10^6)/N)
2.99,因爲我的時鐘頻率爲2.99Ghz
幾點:
我的用戶空間程序使用集合關係綁定到單個核心。
我使用的內核2.6.22.14
要切換上下文,而我的鉤內停止的內核,我用preempt_disable()和preempt_enable()。因此它不會計算其他內核線程的執行時間。即使這樣,因爲我的鉤子使用了一些I/O,我的線程可能會自動釋放控制器,或者可能會發生一些可能會增加總週期數的中斷。
問題: 如何在內核中精確測量函數執行時間?
嘗試禁用BIOS中的頻率更改並重新測量週期 – osgx 2011-01-11 08:47:35