[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%附近,基本上可以算是一条直线了。这些波动大概就是由于其他程序工作引起的。
问题二
对上面的解法设置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%的占用率。
问题三
为了让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++;
}
}
实验结果如下图所示,不过结果还不是很好,一些细微的地方调整一下也许曲线会更完美一些。
我对这个的研究还不够详细,如果有错误的地方欢迎指正!
在单核处理器的环境下代码这么写差不多了,我一会就去把多核打开,电脑这样太卡顿了,过两天再把多核处理器下调整CPU使用率的方法研究一下。
版权声明:本文为博主原创文章,未经博主允许不得转载。