原始程序

最近在写某个程序, 伪代码大意是这样的.

1
2
3
4
5
6
7
8
9
10
start = get_time();
while(!stop) {
// some actions

if(get_time() - start > 1s) { // 间隔超过1s(物理上的1s)
// other actions.

start = get_time();
}
}

我们都知道之前统计程序时间时使用clock()函数, 可以获得程序的运行时间.

比如

1
2
3
4
5
6
7
clock_t start = clock();

// actions.

clock_t end = clock();

int run_time = end - start;

程序中的一点问题

在程序中, 我也这样使用clock()函数, 而后的结果却不尽如意: 程序效率极低(可能是我间隔太短, 导致反复的调用)

  1. 我的程序中间隔1s是需要比较精确的, 也就是上一次操作和这一次操作必须要真正的的间隔1s.
  2. clock()只统计了CPU运转时间, 如果程序休眠, 那么, CPU时间是不会被占用的. 也就是说clock()统计的时间间隔, 可能要比真实的时间要长一点, 至于这长的一点 我也不知道该怎么计算.

我的实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// 一个简单的耗时函数
int frequency_of_primes (int n) {
int i,j;
int freq=n-1;
for (i=2; i<=n; ++i) for (j=sqrt(i);j>1;--j) if (i%j==0) {--freq; break;}
return freq;
}


clock_t start = clock();

// 这里不可以使用sleep函数, sleep时时钟不会

// sleep(2);
// Get clock 0.000022

frequency_of_primes(999999);
// Get clock 1.579848

clock_t end = clock();
printf("Get clock %fs\n", (double)(end - start) / CLOCKS_PER_SEC);

如果调用sleep(2), 那么clock()的变化基本没有, 也就说明, 在休眠状态中 CPU时钟是不会被消耗的.

正确的时间统计

对于轮询的计时器, 推荐使用clock_gettime()函数.

1
2
3
4
5
6
7
8
9
10
11
12
struct timespec start, finish;
double elapsed;

clock_gettime(CLOCK_MONOTONIC, &start);
sleep(2);

clock_gettime(CLOCK_MONOTONIC, &finish);

elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;

printf("Now we get %fs\n", elapsed);

上述的代码可以在gist看到.