现在的位置: 首页 > 综合 > 正文

18、深入理解计算机系统笔记:测量程序执行时间

2011年08月15日 ⁄ 综合 ⁄ 共 1966字 ⁄ 字号 评论关闭

1、人不能够觉察短于大约100ms的时间段。

2、计算机有一个外部计时器,它周期性地向处理器发送中断信号。这些中断信号之间的时间被称为间隔时间(interval time)。

3、从一个进程切换到另一个进程需要几千个时钟周期来保存当前当前进程的状态。典型的计时器间隔范围是110ms

4、通过间隔计数(interval counting)来测量时间

OS也用计时器(timer)来记录每个进程使用的累计时间,这种信息提供的是对程序执行时间不那么精确的测量值。这种方法只对长持续时间(到少1s)的测量有用。

OS维护着每个进程使用的用户时间量和系统时间量的计数值。

通过如下两种方法读进程的计数器

1shell的命令前加time

    结果前两个值为命令进程执行的用户和系统时间,第三个值为执行经过的总时间。

2)调用函数times来读进程的计时器。

示例代码

#include <sys/times.h>
struct tms {
clock t tms utime; /* user time */
clock t tms stime; /* system time */
clock t tms cutime; /* user time of reaped children */
clock t tms cstime; /* system time of reaped children */
}

clock t times(struct tms *buf);
Returns: number of clock ticks elapsed since system started

#include <time.h>
clock t clock(void);
Returns: total time used by process

这些时间测量值是以时钟滴答(clock tick)为单位来表示的。定义的常数CLK_TCK指明每秒的时钟滴答数。The fields indicating child times give the

accumulated times used by children that have terminated and have been reaped.(意为每个子域给出了我们可能需求的一个子时间项,这些子时间项是由已经终止,且被回收的子进程所累积)

因此,times不能用来监视任何正在进行的子进程所使用的时间。作为返回值,返回的是从系统启动开始已经经过的时钟滴答总数。

3ANSI C定义了一个clock函数来测量当前进程使用的总时间。要将clock函数报告的时间变成秒数,要除以定义常数CLOCKS_PER_SEC,这个常数不一定与CLK_TCK相同。

5、通过周期计数器来测量时间

CPU上有一个特殊的计时器,每个时钟周期加1

本书9.3.1节讲述了通过汇编代码来获取这个周期计数器的值的过程。可以得到在微观尺度上很好的测量值。

同时讲述了k次最优测量方法。

6、通过gettimeofday函数的测量

gettimeofday函数查询系统时钟(system clock)以确定当前的日期和时间。

示例代码

#include "time.h"
struct timeval {
long tv sec; /* Seconds */
long tv usec; /* Microseconds */
}
int gettimeofday(struct timeval *tv, NULL);
Returns: 0 for success, -1 for failure

linux中,第二个参数设置成NULL,因为它指向一个未被实现的执行时区校正的特性。

示例代码

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

/* $begin tod */
#include <sys/time.h>
#include <unistd.h>

static struct timeval tstart;

/* Record current time */
void start_timer()
{
    gettimeofday(&tstart, NULL);
}

/* Get number of seconds since last call to start_timer */
double get_timer()
{
    struct timeval tfinish;
    long sec, usec;

    gettimeofday(&tfinish, NULL);
    sec = tfinish.tv_sec - tstart.tv_sec;
    usec = tfinish.tv_usec - tstart.tv_usec;
    return sec + 1e-6*usec;
}
/* $end tod */

实现依赖于gettimeofday是如何实现的,而gettimeofday的实现随系统不同而不同。

7、更多关于测量的方法和技巧,参见9.4,9.5,9.6,9.7

<Computer Systems:A Programmer's Perspective>

抱歉!评论已关闭.