[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%附近,基本上可以算是一条直线了。这些波动大概就是由于其他程序工作引起的。
解法一 50%使用率-任务管理器
解法一 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%的占用率。
CPU70%占用率

问题三

为了让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使用率的方法研究一下。

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

 

posted @ 2015-04-08 18:22  夏方方  阅读(1627)  评论(0编辑  收藏  举报