活动地址:CSDN21天学习挑战赛
前言
对内核或驱动代码做性能优化时,常常要测量一段代码执行时所消耗的时间,这时候就不得不说一个时间函数 ktime_get()。
在一段代码前后各使用 ktime_get() 获取时间,计算其差值,就是这段代码运行消耗的时间。
ktime_get() 能够精确到纳秒级。
示例
include/linux/netdevice.h
static inline netdev_tx_t netdev_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq, bool more)
{
const struct net_device_ops *ops = dev->netdev_ops;
int rc;
ktime_t start, diff;
/* 1. 获取当前时间 */
start = ktime_get();
/* 2. 计算时间差,单位纳秒 */
diff = ktime_sub(ktime_get(), start);
printk("1diff time = %lldns\n", ktime_to_ns(diff));
/* 1. 获取当前时间 */
start = ktime_get();
rc = __netdev_start_xmit(ops, skb, dev, more);
/* 2. 计算时间差,单位纳秒 */
diff = ktime_sub(ktime_get(), start);
printk("2diff time = %lldns\n", ktime_to_ns(diff));
if (rc == NETDEV_TX_OK)
txq_trans_update(txq);
return rc;
}
上述代码想要获取执行一次 __netdev_start_xmit() 所消耗的时间。为了考察 ktime_get() 误差,我连续两次调用 ktime_get(),看下其自身消耗的时间。
运行
1diff time = 333ns
2diff time = 13000ns
1diff time = 667ns
2diff time = 13333ns
1diff time = 667ns
2diff time = 10333ns
1diff time = 667ns
2diff time = 13334ns
1diff time = 667ns
2diff time = 5333ns
1diff time = 333ns
2diff time = 10666ns
1diff time = 667ns
2diff time = 13000ns
1diff time = 666ns
2diff time = 7000ns
1diff time = 334ns
2diff time = 10334ns
1diff time = 666ns
2diff time = 6666ns
1diff time = 666ns
2diff time = 8000ns
1diff time = 667ns
2diff time = 10667ns
1diff time = 667ns
2diff time = 13667ns
1diff time = 334ns
2diff time = 6000ns
1diff time = 666ns
2diff time = 11333ns
1diff time = 667ns
2diff time = 8334ns
1diff time = 666ns
2diff time = 10333ns
1diff time = 667ns
2diff time = 10667ns
1diff time = 334ns
2diff time = 12000ns
1diff time = 667ns
2diff time = 13666ns
1diff time = 333ns
2diff time = 13667ns
1diff time = 666ns
2diff time = 13333ns
1diff time = 667ns
2diff time = 11334ns
1diff time = 334ns
2diff time = 10333ns
1diff time = 334ns
2diff time = 12000ns
1diff time = 667ns
2diff time = 12667ns
1diff time = 333ns
2diff time = 5334ns
1diff time = 1666ns
2diff time = 13000ns
1diff time = 667ns
2diff time = 5000ns
1diff time = 666ns
2diff time = 10667ns
1diff time = 666ns
2diff time = 13000ns
1diff time = 334ns
2diff time = 13667ns
1diff time = 333ns
2diff time = 13333ns
1diff time = 666ns
2diff time = 11666ns
1diff time = 333ns
2diff time = 6000ns
1diff time = 333ns
2diff time = 13666ns
1diff time = 667ns
2diff time = 14000ns
1diff time = 334ns
2diff time = 13667ns
1diff time = 666ns
2diff time = 14666ns
1diff time = 333ns
2diff time = 13000ns
1diff time = 334ns
2diff time = 11667ns
可以看到 ktime_get() 自身会消耗 333ns 或 666ns 时间,这两个数字看起来就很古怪,等有空了研究下机器周期、时钟周期、指令周期,看看从这里能否找到解答该现象的答案(PS:当前系统cpuinfo_cur_freq = 792000)。
2diff time 对应的时间就是执行一次 __netdev_start_xmit() 所消耗的时间,大概是 13000ns。有了这个定量的性能参数,对于我们找到性能瓶颈是一个莫大的帮助。