让CPU占有率听从你的指挥

  写一个程序,让用户决定Windows任务管理器Task Manager的CPU占有率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:

  1 CPU的占用率固定在50%,为一条直线

  2 CPU的占用率为一条直线,具体占用率由命令行参数决定

  3 CPU的占用率是一条正弦曲线


分析:

  有一名同学写了如下的代码

 while(true)

{

  if(busy)

     i++;

   else
}

然后他就陷入了苦苦思索:else干什么呢?怎样才能让电脑不做事情呢?CPU的占用率为0的时候,到底是什么东西在占用CPU?另一名同学花很多时间构想如何“深入内核,以控制CPU占用率”,可是事情真的有这么复杂么?

如果不小心写了一个死程序,CPU占用率就会跳到最高,并且一直保持在100%。一般情况下,CPU占用率会很低,但是,当用户运行一个程序时,执行一些复杂的操作时,CPU的占用率会急剧升高。当用户晃动鼠标的时候,CPU的使用率也会有小幅度的变化。

那当任务管理器报告CPU为0时,到底是谁在使用CPU呢?通过任务管理器的进程process一栏可以看到,System Idle Process占用了CPU的空闲的时间,系统中有那么多的进程,他们什么时候能闲下来呢,答案很简单,这些程序或者在等待用户的输入,或者在等待某些事情发生,或者主动进入休眠状态。

在任务管理器的一个刷新周期内,CPU忙的时间和刷新周期总时间的比率就是CPU的占用率,也就是说,任务管理器中显示的是每个刷新周期内CPU占用率统计平均值。



解法一:

  要操纵CPU的占用率曲线,就需要使CPU在一段时间内跑busy和idle两个不同的循环loop,从而实现不同的时间比例。

busy loop可以通过执行空循环来实现,idle可以通过sleep()来实现。

问题的关键在于如何控制两个loop的时间,我们先实验一下sleep一段时间,然后循环n次,估计n 的值。

那么对一个空循环for(i=0;i<n;i++);又该如何来估算这个最合适的n值,我们都知道CPU执行的是机器指令,而最接近机器指令的语言就是汇编语言,所以我们可以先把这个空循环写成汇编代码在进行分析:

loop;

mov dx i                     ;将i置入dx寄存器

inc dx                         ;将dx寄存器加1

mov i dx                     ;将dx中的值赋回i

cmp i n                       ;比较i和n

jl loop                         ;i小于n时则重复循环

假设这段代码要运行的CPU是P4 2.4GHz。现代CPU每个时钟周期可以执行两条以上的代码,我们取平均值两条,于是有,(2400000000*2)/5=960000000(循环/秒),也就是说CPU1秒钟可以运行这个空循环960000000次。不过我们还是不能简单地将n=960000000,然后sleep(1000)了事。如果我们让CPU工作一秒钟,然后休息一秒钟,波形很有可能就是锯齿形状的 先达到一个峰值,然后跌倒一个很低的占用率。

我们尝试着降低两个数量级,令n=960000000,而睡眠时间则相应的改为10毫秒,用10毫秒是因为比较接近Windows的调度时间片。如果选的太小,会造成线程频繁的被唤醒和挂起,无形中又增加了内核时间的不确定性。

int main()

{

  for(;;)

   {

     for(int i =0;i<9600000;i++)

         ;

         Sleep(10);

    }

    return 0;

}

在不断地调整9600000的参数后,我们就可以在一台指定的机器上获得一条大致稳定的50%CPU占用率直线。

使用这种方法要注意两点:

 1 尽量减少sleep/awake的频率,以减少操作系统内核调度程序的干扰;

 2 尽量不要调用system call,因为他也会导致很多不可控的内核运行时间。

该方法有明显的缺点,不能适应机器差异性。一旦换了一个CPU,我们又得重新估算n值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值