Fork me on GitHub

控制CUP占用率曲线

       在《编程之美》上看过一道面试题就是要求:输出cup占用率的曲线图

今天看到了一篇文章就试试看看:

#include <iostream>
#include <cmath>
#include <ctime>
#include <windows.h>

using namespace std;

//得到循环0xFFFFFFFF次用的秒数
unsigned int test()
{
    unsigned int c = 0xFFFFFFFF;

    time_t t1, t2;
    time(&t1);

    for (unsigned int i = 0; i < c; i++)
        ;
    time(&t2);
    return (unsigned int)(t2 - t1);

}

#define T  20000                                          //周期时间 20秒
#define C  100                                            //采样点时间间隔
#define PI 3.1415                                         //PI

const unsigned int _count = 0xFFFFFFFF / (test() * 1000);    //采样间隔可以执行的循环数目  //考虑到了当前系统的运行程序
const unsigned int N = T / C;                                //周期内采样点数目
unsigned int v[N] = { 0 };                                   //所有采样点连续执行循环数
unsigned int mt[N] = { 0 };                                  //所有采样点休眠毫秒数

int main()
{
    //指定运行CPU
    SetThreadAffinityMask(GetCurrentThread(), 8);
    
    for (int i = 0; i < N; i++)
    {
        double x = 2 * PI * i / N;
        double r = (sin(x) + 1) / 2;

        mt[i] = C - r * C;      //空闲时间
        v[i] = r * C * _count;  //忙的时间,考虑当前cup使用情况
    }
    for (;;)
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < v[i]; j++)
                ;
            Sleep(mt[i]);
        }
    }
}

实验结果:指定运行cup和核数有关吧

首先什么是CPU占用率?

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

因此可以写个程序,在一个刷新周期中,一会儿忙,一会儿闲,调节忙/闲比例,就可以控制CPU占有率!

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

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

 2.    CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100);

 3.    CPU的占用率状态是一个正弦曲线。

 直线cpu:使x=0即可:

#include <iostream>
#include <cmath>
#include <ctime>
#include <windows.h>

using namespace std;

//得到循环0xFFFFFFFF次用的秒数
unsigned int test()
{
    unsigned int c = 0xFFFFFFFF;

    time_t t1, t2;
    time(&t1);

    for (unsigned int i = 0; i < c; i++)
        ;
    time(&t2);
    return (unsigned int)(t2 - t1);

}

#define T  20000                                          //周期时间 20秒
#define C  100                                            //采样点时间间隔
#define PI 3.1415                                         //PI

const unsigned int _count = 0xFFFFFFFF / (test() * 1000);    //采样间隔可以执行的循环数目
const unsigned int N = T / C;                                //周期内采样点数目
unsigned int v[N] = { 0 };                                   //所有采样点连续执行循环数
unsigned int mt[N] = { 0 };                                  //所有采样点休眠毫秒数

int main()
{
    //指定运行CPU
    SetThreadAffinityMask(GetCurrentThread(), 1);
    
    ////正弦cpu
    //for (int i = 0; i < N; i++)
    //{
    //    double x = 2 * PI * i / N;
    //    double r = (sin(x) + 1) / 2;

    //    mt[i] = C - r * C;
    //    v[i] = r * C * _count;
    //}
    //for (;;)
    //{
    //    for (int i = 0; i < N; i++)
    //    {
    //        for (int j = 0; j < v[i]; j++)
    //            ;
    //        Sleep(mt[i]);
    //    }
    //}

    //直线cpu
    for (int i = 0; i < N; i++)
    {
        double x = 2 * PI * i / N;
        x = 0;
        double r = (sin(x) + 1) / 2;

        mt[i] = C - r * C;
        v[i] = r * C * _count;
    }
    for (;;)
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < v[i]; j++) 
                ;
            Sleep(mt[i]);
        }
    }
}

//没有考虑现在系统cpu使用情况
//#include <windows.h>
//#include <math.h>
//int main(void)
//{
//    SetThreadAffinityMask(GetCurrentProcess(), 1);
//    const double SPLIT = 0.01;
//    const int COUNT = 200;
//    const double PI = 3.14159265;
//    const int INTERVAL = 300;
//    DWORD busySpan[COUNT]; //array of busy time
//    DWORD idleSpan[COUNT]; //array of idle time
//    int half = INTERVAL / 2;
//    double radian = 0.0;
//    for (int i = 0; i < COUNT; i++)
//    {
//        busySpan[i] = (DWORD)(half + (sin(PI*radian)*half));
//        idleSpan[i] = INTERVAL - busySpan[i];
//        radian += SPLIT;
//    }
//    DWORD startTime = 0;
//    int j = 0;
//    while (true)
//    {
//        j = j%COUNT;
//        startTime = GetTickCount();
//        while ((GetTickCount() - startTime) <= busySpan[j])
//            ;
//        Sleep(idleSpan[j]);
//        j++;
//    }
//    return 0;
//}

结果:

 

reference:

   CPU正弦曲线

posted @ 2017-01-14 11:28  ranjiewen  阅读(489)  评论(0编辑  收藏  举报