第九章 测量程序执行时间
计算机用来计算时间流逝的两种基本机制:一种是基于低频率计时器,它会周期性中断处理器,另一种基于计数器,每个时钟周期计数器会加1
当调度程序从进程A切换到进程B时,它必须进入内核模式保存进程A的状态(仍被认为是进程A的一部分),然后恢复进程B的状态(被认为是进程B的一部分)。因此每次从一个进程过渡到另一个进程期间,是由内核活动的。
从应用程序的角度出发,可以把时间流看成是两种时间段的交替,一种时间段里程序是活动的(在执行它的指令),另一时间段里程序是不活动的(等待被操作系统调用)。
通过间隔计数器来测量时间:操作系统也用计时器(timer)来记录每个进程使用的累计时间。这种信息提供的事对程序执行时间不那么准确的测量值。
操作系统维护着每个进程使用的用户时间量和系统时间量的计数值,当计时器中断发生时,操作系统会确定哪个进程是活动的,并且对那个进程的一个计数值增加计时器间隔时间,如果系统是内核模式中执行的,那么就增加系统时间,否则就增加用户时间。
周期计数器,可以提供更高的精确度。(可以测量一个程序执行中两个不同点之间经过的时间)每个时钟周期会加1.但是不是所有的处理器都有这样的计数器的,而且有这样计数器的处理器在实现细节上也各不相同。因此程序员无法用统一的、与平台无关的接口使用这些计数器,另一方面只用少量的汇编代码,通常很容易就为某个特定的机器创建一个程序接口。
上下文切换影响:如果在两次调用计数器例程之间,有另外某个进程执行了,那么这段代码就很容易产生令人误解的结果。如果机器负载很重,或者若果P的运行时间特别长,这就特别成问题。
高速缓存和其他因素的影响:高速缓存和分支预测造成的计时变化比上下文切换造成的要小一些。
K次最优测量方法:虽然我们使用周期计时器测量容易受上下文切换。高速缓存和分支预测引起的误差的影响,一个重要特征就是这些误差总是导致过高地估计真实的执行时间,处理器做的事情都不会认为地加速一个程序的执行。即使有很多影响结果的因素,我们仍然可以利用这个属性来获得执行时间可靠地测量值。除了最新版的Linux会导致非常高的计时器中断开销,严重影响测量准确性。这种测量方法在多种机器上都工作的相当好,对于负载很轻的处理器,在大多数机器上,即使是对长持续时间的计算,它总是能得到准确的结果。大多数系统都有某个最大执行时间当最大执行时间超出了测量界限,那么准确性就会变的非常糟糕。
除去这个偏差需要确定两个因素:
1、处理一个计时器中断需要多少时间。2、在我们测量的时间段内发生率多少次计数器中断。
经验:
1、每个系统都是不同的。
2、实验可以非常有启迪性。
3、在负载很重的系统上获得准确的计时特别困难。
4、实验建立必须控制一些造成性能变化的因素。