[C++]让CPU使用率曲线呈现为正弦曲线(一)

看《编程之美》的第一题就很有意思:

写一个程序,让用户来决定Windows任务管理器的CPU占用率。可以实现下面三种情况:
1. CPU的占用率固定在50%,为一条直线;
2. CPU的占用率为条直线,但是具体占用率由命令行参数觉得(1~100);
3.CPU的占用率状态是一个正弦曲线

问题一

我开始是按照书上的做法来的,让CPU在一半的时间工作(一个空循环),另一半的时间Sleep。

#include<iostream>
#include<Windows.h> using namespace std; //工作和空闲各10ms
int busyTime = 10;
int idleTime = 10;
void CPU(); int main()
{
CPU();
return 0;
} void CPU(){
INT64 startTime = 0;
while (true){
startTime = GetTickCount();
while ((GetTickCount()-startTime)<=busyTime)
{
;
}
Sleep(idleTime);
}
}

不过这个解法在我的电脑上并不可行,书上讨论的情况是只有单个CPU的环境,而我的CPU是双核四线程的,运行这个程序CPU使用率达不到50%,甚至当我把 Sleep(idleTime); 这句注释掉之后,CPU使用率也只不过30%左右。

解决这个问题我想到了两种办法:

  • 一是多线程,创建四个线程,让它们都运行这个CPU()函数;
  • 二是简单粗暴地在 Bois 里面设置一下,只使用CPU的一个核心,一个线程。

因为之前还没有接触过Windows多线程编程,所以在这儿我先偷懒选用了第二种方法,只用单个CPU核心(不过这样电脑卡顿了不少)。再次运行程序,从下面的截图可以看到,CPU使用率基本上就维持在了50%附近,基本上可以算是一条直线了。这些波动大概就是由于其他程序工作引起的。
[C++]让CPU使用率曲线呈现为正弦曲线(一)
[C++]让CPU使用率曲线呈现为正弦曲线(一)

问题二

对上面的解法设置level参数就可以使之呈现不同的使用率。

#include<iostream>
#include<Windows.h>
#include<cmath> using namespace std; int eachTime = 100;
void CPU(int busy,int idle); int main()
{
int level;
cin >> level;
int busyTime = eachTime*level / 100;
int idleTime = eachTime - busyTime; CPU(busyTime,idleTime);
return 0;
} void CPU(int busy, int idle){
INT64 startTime = 0;
while (true){
startTime = GetTickCount();
while ((GetTickCount()-startTime)<=busy)
{
;
}
Sleep(idle);
}
}

下图为输入70时程序运行时性能监视器的曲线,基本上符合70%的占用率。
[C++]让CPU使用率曲线呈现为正弦曲线(一)

问题三

为了让CPU使用率曲线呈现为一条正弦曲线,只要先算出一个正弦值的数组,依次根据数组中的值设定程序工作和空闲的时间。
先设置一个时间间隔eachTime,取其一半halfTime。每个工作时间busy=halfTime+sin(delta)*halftime,空闲时间则为eachTime-busy

#include<iostream>
#include<Windows.h>
#include<cmath> using namespace std; int eachTime = 100;
int halfTime = eachTime / 2;
int busy[200];
int idle[200];
const int COUNT = 200;
const double SPLIT = 0.01;
const double PI = 3.14159265;
void CPU(); int main()
{
double delta = 0;
for (int i = 0; i <COUNT; i++){
delta = i*SPLIT*PI;
cout << delta << endl;
double s = sin(delta);
busy[i]=s*halfTime+halfTime;
idle[i] = eachTime-busy[i];
}
CPU();
return 0;
} void CPU(){
INT64 startTime = 0;
int i = 0;
while (true){
i %= COUNT;
startTime = GetTickCount();
while ((GetTickCount()-startTime)<=busy[i])
{
;
}
Sleep(idle[i]);
i++;
}
}

实验结果如下图所示,不过结果还不是很好,一些细微的地方调整一下也许曲线会更完美一些。
[C++]让CPU使用率曲线呈现为正弦曲线(一)
[C++]让CPU使用率曲线呈现为正弦曲线(一)

我对这个的研究还不够详细,如果有错误的地方欢迎指正!
在单核处理器的环境下代码这么写差不多了,我一会就去把多核打开,电脑这样太卡顿了,过两天再把多核处理器下调整CPU使用率的方法研究一下。

版权声明:本文为博主原创文章,未经博主允许不得转载。

上一篇:idea Invalid bound statement (not found):


下一篇:4408: [Fjoi 2016]神秘数