测量程序的运行时间

从这本书中整理而来: Computer Systems ----  A programmer's perspective   first edtion   Chapter 9


要精确测量程序的运行时间非常困难,主要因为:

1. concurrent:OS并发运行多个process,在这些process间进行切换

2. 运行时间受到各种计算机环境的影响:如Cache的命中率


两种测量机制:

1. 基于外部时钟(Interval Counting)

计算机硬件中有一个external timer,其主要作用就是每个一定时间(通常设置为1-10 ms间某个数),向CPU发送中断信号。CPU接收到该中断信号后,立即执行相应的中断处理程序。此时OS进入kernel mode,运行系统代码,查看是否应该进行进程切换。利用这个external timer,OS可以为每个进程记录其所消耗的时间。

具体工作方式:

当timer中断后,OS查看在中断之前是哪个process在运行,就把一次中断间隔时间算在这个process的账上。对每一个process所花时间,实际上细分为user time和system time,user time表示执行用户程序所用时间,system time表示执行内核系统代码所用时间,OS根据所在的mode(user mode和kernel mode)来区分。

如何使用Interval Counting来计时:

第一,Linux下的time命令

   该命令可以返回某个程序的运行时间的具体参数。

第二,C standard library  <time.h>中clock函数

clock_t  clock(void);

该函数返回当前进程到目前为止所使用的clock数。

测量时间的方法:

clock_t beg = clock();

// 待测量时间的代码

clock_t end = clock();

double seconds = (double) (end - beg) / CLOCKS_PER_SEC;

准确性:这种方法最多能识别到interval 级别(10ms左右),而且由于其实在中断时将这个interval全记录到前一刻的运行的那个process上,所以会造出误差,但当运行时间较长时,这种误差可相互抵消。因此,基于外部时钟的方法,适用于运行时间 > 1s 的情况,此时可以测得比较准确的数据。

2. 基于CPU时钟周期(Cycle Counters)

有些硬件CPU内部有一个寄存器专用于存放系统到目前为止运行了多少个CPU时钟周期。如interl 的IA32体系结构中有一个64位的寄存器用于该目的。使用该寄存器可以测量程序运行的CPU时钟周期数,进而算出运行时间。

问题:

和具体硬件相关,有可能一些硬件没有这样的寄存器,即使有,也要使用硬件相关的汇编语言来读取该寄存器。

该寄存器并不是和process相关,而是全部程序公用的,那么进程切换怎么办?

因此,Cycle Counter方法比较适用于程序运行时间较短的情况,理想情况下 < 10ms最准确,因为此时进行进程切换的可能性较低。

如何使用:

第一,使用gettimeofday函数(POSIX标准),注意其底层到底是使用什么方式(Interval Counting还是Cycle Counters)取决于具体的系统(硬件和OS)

代码参考Computer Systems ----  A programmer's perspective   first edtion 官网下载的code中: code/perf/tod.c
第二,使用汇编语言直接访问底层硬件,前提是硬件支持

IA32平台下代码参考Computer Systems ----  A programmer's perspective   first edtion 官网下载的code中: code/perf/clock.c

The K-Best Measurement Scheme:用于修正Cycle Counter方法中产生的误差。具体参考Computer Systems ----  A programmer's perspective   first edtion 9.4.3 节。


如何消除Cache的影响按程序要运行的实际环境来模拟。若该程序在实际情况下经常访问新的数据,则可以写程序将Cache先清空;反之亦然。注意Cache有两种,用于指令的cache和用于数据的cache。


总结:

1. 如果程序运行时间 大于1s,则采用interval counting就可以取得比较精确数据。

2. 如果程序运行时间小于10ms,则采用cycle counters可以获取非常精确的数据,即使测试的时候系统负载很重(很多进程同时运行)。采用 K-Best Measurement Scheme,底层使用cycle counters。

3. 如果运行时间介于 10ms和1s之间,则想要获取准确时间必须非常小心:采用 K-Best Measurement Scheme,底层使用cycle counters;同时测试的时候系统必须负载很轻(lightly loaded)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值