【编程之美】CPU

今天开始看编程之美 。第一个问题是CPU的使用率控制,微软的问题果然高大上,我一看就傻了,啥也不知道。没追求直接看答案试了一下。发现自己电脑太好了,4核8线程,程序乱飘。加了一个进程绑定,可以控制一个CPU的占有率。

代码结果如下:

#include"stdio.h"
#include <Windows.h>

void main()
{
    //前三行可以不要
    SYSTEM_INFO SystemInfo;
    GetSystemInfo(&SystemInfo);
    int CpuNum=SystemInfo.dwNumberOfProcessors; //获取cpu数目
    SetThreadAffinityMask(GetCurrentThread(), 1);     //线程与cpu绑定
    while(1)
    {
        for(int i=0;i<3400000000;i++);
        Sleep(10);
    }    
}

现在的疑问是,不知道如何指定具体的某一个CPU. SetThreadAffinityMask的第二个参数改了后和自己想要的不一样。也不知道如何实现所有CPU占有率的同时控制。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

第二个版本 按照书中给的可以根据不同的CPU精确计算时间的代码  效果好很多

//比初始最简单的版本好很多 CPU使用中可以得到非常漂亮的直线 不像之前有锯齿
#include<stdio.h>
#include<Windows.h>

void main()
{
    const int busyTime=10;              //10ms
    const int idleTime=busyTime;        //50% cpu useage
    int startTime=0;

    SetThreadAffinityMask(GetCurrentThread(), 1); //cpu绑定

    while(1)
    {
        int startTime=GetTickCount();
        //busy loop
        while(GetTickCount()-startTime<=busyTime);

        //idle loop
        Sleep(idleTime);
    }

}

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

第三个版本 正弦曲线 可以调周期和赋值等参数

开始脑子晕了 总是搞不清楚关系 后来看了答案 发现答案的思路很清晰 自己又静下心来分析了一下正弦函数的表达式修改一下自己的代码 也实现了功能 不过曲线上个抖动比较大。

计算公式:

一次取样的时间 busytime+idletime=常数  单位毫秒

忙的时间占得百分比就是正弦函数计算的结果:

busytime/(busytime+idletime)=middle+amplitude*sin(x)

每一次的x值与周期有关

x=n*(busytime+idletime)/1000T      周期单位是秒   n每循环一次加1

代码:

#include<stdio.h>
#include<Windows.h>
#include<math.h>
#include<stdlib.h>
#define Mine 1
#define Answer 0
#if Mine
void main()
{
    SetThreadAffinityMask(GetCurrentThread(), 1); //cpu绑定
    double busyTime;             
    double idleTime;
    double onceTime=200; //一次抽样300ms busyTime+idleTime=300
    float up=0.8;        //正弦曲线波峰值
    float down=0.2;      //正弦曲线波谷值
    int T=60;            //正弦曲线周期s
    int startTime=0;
    int n=0;
    
    float amplitude=(up-down)/2; //振幅
    float middle=(up+down)/2;    //正弦曲线中心点
    while(1)
    {
        
        busyTime=onceTime*(middle+amplitude*sin(2*3.1415*n*onceTime/(1000*T)));
        idleTime=onceTime-busyTime;

        int startTime=GetTickCount();
        
        //busy loop
        while(GetTickCount()-startTime<=busyTime);

        //idle loop
        Sleep(idleTime);
        n=n+1;
    }

}

#endif

#if Answer
const int SAMPLING_COUNT=200;      //抽样点数量
const double PI=3.1415926535;
const int TOTAL_AMPLITUDE=300;     //每个抽样点对应的时间片

int main()
{
    SetThreadAffinityMask(GetCurrentThread(), 1);
    long busySpan[SAMPLING_COUNT];
    int amplitude=TOTAL_AMPLITUDE/2;
    double radian=0.0;
    double radianIncrement=2.0/(double)SAMPLING_COUNT;
    for(int i=0;i<SAMPLING_COUNT;i++)
    {
        busySpan[i]=(long)(amplitude+(sin(PI*radian)*amplitude));
        radian+=radianIncrement;
    }
    int startTime=0;
    for(int j=0;;j=(j+1)%SAMPLING_COUNT)
    {
        startTime=GetTickCount();
        while((GetTickCount()-startTime)<=busySpan[j]);
        Sleep(30+TOTAL_AMPLITUDE-busySpan[j]);
    }
    return 0;
}


#endif

书上代码结果:

自己写得代码结果:

 

 

 

 

 

抖动很大 而且onceTime变小后抖动更大了 在onceTime很小的时候 busytime/onceTime=0.5 时曲线都会饱和截至,不知道原因。

注:所有的图都是第一个cpu的结果有效。

posted @ 2014-02-25 21:20  匡子语  阅读(539)  评论(1编辑  收藏  举报