我正在使用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