《编程之美》读书随笔之一:让CPU占有率曲线听你指挥

这个问题的描述如下:写一个程序,让用户来觉得Windows的任务管理器(Task Messager)上的CPU占有率,编程语言不限。程序越精简越好,可以实现下面的功能:

第一、CPU的占有率固定在50%,为一条直线。

第二、CPU占有率为一条直线,占有率由命令行参数决定(范围是1-100)。

第三,CPU的占有率是一条正弦曲线。

在解这个题目之前,要先了解一下什么是CPU的占有率,从“占有”这两个字来看,CPU的占有率应该是CPU忙碌的时间占总时间的比率。题目中让我们控制CPU的占有率,就是让我们控制CPU什么时候忙碌,什么时候空闲,让它听从我们的指挥。

很容易,我们就想到了通过循环和判断来实现这个功能,在一半的时间内,我们让CPU运行自己的程序,另外一半,使用sleep,让CPU空闲,可以运转其他的程序,这个时间控制使用一个变量来控制,让变量自增或者自减。

解法一:在《编程之美》这本书里面讲的很清楚,循环确实可以做到,但是我们如何知道一个空循环所需要的时间呢,这个就需要自己估算了,在计算机中,任何程序到底层之后都会转换成机器指令,在接近机器指令的最近的语言就是汇编语言,我们可以通过分析汇编语言来分析一个空循环所需的时间。

LOOP:
mov dx i         ;将i放入寄存器dx中
inc dx             ;将dx自加1
mov i dx         ;将寄存器中的值赋值给i
cmp i n           ;判断i的值是否为n
jl loop             ;循环

从这几行汇编语言中,我们可以看出来,一次循环需要运行5条机器指令,假设我们每个时钟周期可以执行两条以上的代码,CPU是频率是2.6GHZ,这是我的计算机CPU频率,这样没一秒钟就可以执行上述代码(2 600 000 000*2)/5 = 1 040 000 000次。但是我们的CPU空闲时间怎么确定呢,是不是直接就是一秒,也就是sleep(1000)就行了,答案是否。原因是在Windows下,CPU线程切换需要时间。在书上说的,CPU切换的时间片差不多就是10毫秒,这样我们就可以设定为sleep(10),得到的程序如下:

	for(;;)
	{
		for(int i = 0; i < 10400000;i++);
		Sleep(10);
	}

不断调整循环次数,可以保证CPU的占有率曲线是一天直线,但是不是很稳定。该方法有一个很大的缺点就是,一旦换了一个CPU,我们必须重新计算循环次数。现在就需要一个动态的循环次数来适应CPU。

解法二:使用GetTickCount()函数得到系统从启动到现在所经历的毫秒数,也就是时间。代码如下:

void fun1()
{
	int busyTime = 10;
	int idleTime = busyTime * 1.0; //调整这个1.0的值,以达到50%的标准,不同的计算机上是不同的。
	int ret = SetThreadAffinityMask(GetCurrentThread(),0x00000001);//使这个程序跑在第一个CPU核心
	INT64 startTime = 0;
	while (1){
		startTime = GetTickCount(); 
		while((GetTickCount() - startTime) <= busyTime)
			;
		Sleep(idleTime);
	}
}

这种方法貌似可以,但是如果在操作系统中,其他进程也占有CPU资源的话,假如其他程序占有10%的CPU资源,那么本程序只能使用40%的CPU资源才能达到效果。这也不算是完全动态。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值