您的位置:首页 > 编程语言

《编程之美》“让CPU占用率听你指挥”学习笔记

2009-02-16 20:22 211 查看
CPU占用率可理解为忙的时间与总的时间的比。若此,自然有第一种解法:空循环与Sleep。具体的方法和代码在《编程之美》的原著中有详述。须注意的是,测出CPU一秒钟能执行的空循环次数(假设能执行C次空循环)后,不能简单地空循环C/2次,然后休息半秒钟。这样得出的曲线虽然大致上是所要求的开头,但是抖动非常厉害。解决方法是什么呢?
解决方法就是使用更小的时间片。如果原来一秒钟可以做C次空循环,那么可以把它们同进降低两个数量级,先空循环C/100次,然后Sleep上10毫秒。这样得出的曲线就非常平滑了。这是对第一种方法的改进:使用更细的粒度实现更精准的模拟。
前两种方法都需要计算出电脑CPU一秒钟内能做多少次空循环。如果换一台电脑就必须重新计算这些数据。其实我们也能感觉得到,既然占用率是一个比值,比值总是相对的。如果我们要求CPU占用率50%,那么在一段时间里让CPU忙一半时间闲一半时间就可以了,这在任何地方都是对的。闲一段时间直接Sleep就可以,那么如何忙一段固定的时间呢?还是用空循环?如果在MSDN上查过clock这个函数,会发现MSDN上给出了一段示例代码如下:
/* Pauses for a specified number of milliseconds. */

void sleep( clock_t wait )

{
clock_t goal;
goal = wait + clock();

while( goal > clock() )
;
}

这不正是使用空循环使CPU忙固定的时间吗?于是新的方法出来了,这种新的方法不需要具体的CPU参数,更加简单、灵巧、通用。下面是自己写的一个完整的让CPU占用率呈现正弦曲线的程序:
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <windows.h>

#define PI		3.1415926535897932
#define TIME_UNIT	500 //单位:毫秒

#define COUNT	100 //一个完整的正弦曲线周期被分割成COUNT个单位

int busy[COUNT], idle[COUNT];

int main() {
const int half = TIME_UNIT / 2;
int i, j;
for(i = 0; i < COUNT; i++) {
//sin(x)的取值范围是[-1,1],为了完整显示,必须给它作些参数调整
//给sin(x)的自变量加上.5*PI等于是把sin(x)左移了/4个周期,
//是为了让它从开始显示而不是%
busy[i] = half*sin(2*PI/COUNT*i+1.5*PI)+half;
idle[i] = TIME_UNIT - busy[i];
}
i = 0;
clock_t begin;
while(1) {
begin = clock();
while(clock() - begin <= busy[i]);
Sleep(idle[i]);
i = (i+1)%COUNT;
}
return 0;
}

以上三种解法,解法三不但简单而且通用,其思想更值得学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: