google/benchmark 是一个用于测试C++代码片段执行效率的工具库。
具体来说,我们可以使用这个工具在完成相同功能的不同实现方法之间对比性能,输出结果如下:
--------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------
Function1 2683 ns 2679 ns 261445
Function2 757 ns 755 ns 934168
Function3 208 ns 208 ns 3366259
Function4 25830 ns 25792 ns 26724
Function5 8307 ns 8298 ns 83651
Function6 14570 ns 14549 ns 48285
其中:
Time 表示real-time,是从进行开始执行到完成所经历的墙上时钟时间(wall clock)时间,包括其他进程使用的时间片(time slice)和本进程耗费在阻塞(如等待I/O操作完成)上的时间。
CPU 表示cpu-time,是CPU执行用户进程操作和内核(代表用户进程执行)系统调用所耗时间的总和,即该进程(包括线程和子进程)所使用的实际CPU时间,包括系统cpu时间和用户cpu时间。
Iterations 表示函数的执行次数,相同时间内执行次数越多,则说明该函数性能更优。
正常情况下,benchmark会将每项测试的时间控制在近乎相同的范围内,这样可以从 Iterations 的大小直观地看出那项测试更快,在上面示例的输出结果中,每一项都用Time * Iterations 得到的总时间也确实是十分接近的(原始单位是纳秒)。
然而今天遇到一个特殊情况,发现计算出来的总时间不一定是一样的,相差非常大,如下:
----------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------
Function1 22934622 ns 22871397 ns 184
Function2 27418982 ns 27260102 ns 1000
Function3 454089889 ns 451374345 ns 29
Function4 472607518 ns 471417032 ns 31
Function5 476287482 ns 474138407 ns 27
Function6 535196862 ns 533773407 ns 27
于是翻查了文档,找到这段描述:
In all cases, the number of iterations for which the benchmark is run is governed by the amount of time the benchmark takes. Concretely, the number of iterations is at least one, not more than 1e9, until CPU time is greater than the minimum time, or the wallclock time is 5x minimum time. The minimum time is set per benchmark by calling MinTime on the registered benchmark object.
也就是说 cpu时间大于配置的最小时间 或者 真实时间大于5倍最小时间,满足任一条件都被当做测试完成可以输出结果,按上面的结果计算后发现确实是满足条件的(测试时配置了最小时间为3秒)。
至于为什么从结果看真实时间跟cpu时间是相近的,却不是先命中 cpu时间大于最小时间 的条件,需要再深入研究,待后续补充。