zoukankan      html  css  js  c++  java
  • [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使用率的方法研究一下。

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

  • 相关阅读:
    S02_CH09_UART串口中断实验
    S02_CH08_ ZYNQ 定时器中断实验
    S02_CH07_ ZYNQ PL中断请求
    S02_CH06_XADC实验
    S02_CH05_UBOOT实验Enter a post title
    S02_CH04_User_IP实验Enter a post title
    S02_CH03_EMIO实验Enter a post title
    S02_CH02_MIO实验Enter a post title
    S02_CH01_Hello World实验
    bzoj4868 [Shoi2017]期末考试
  • 原文地址:https://www.cnblogs.com/xiaff/p/4856505.html
Copyright © 2011-2022 走看看