编程之美 1.1让CPU占用率曲线听你指挥
问题:
1.CPU的占用率固定在50%,为一条直线。
2.问题1的进阶,占用率有参数决定。
3.CPU占用率是一条正弦曲线。
此题目涉及到操作系统API的调用,及对CPU时钟周期的理解,我的电脑配置为:i5-3570k 3.40GHz
解法一:
执行一个循环n次的空循环,然后Sleep()一段时间。
这种方法的不稳定因素太多,例如:机器的差异性、系统内核调度程序的干扰。
实验结果:没有推算出n的值,随便敲了几个,CPU占用率浮动在16%上下。
解法二:
利用GetTickCount()计算busyTime同时Sleep(idleTime),由参数指定busyTime所占比例。
实验结果:虽然busyTime和idleTime相等,但观察CPU占用率还是为25%,可能我的CPU是四核。
解法三:
利用Perfmon实时查询CPU使用率动态调整idleTime
实验结果:因为PerformanceCounter这对象由.Net提供,C#的东西没去试。
正弦曲线解法:
#include <Windows.h> #include <stdlib.h> #include <math.h> #include <tchar.h> const double SPLIT=0.01; //弧度变化率 const int COUNT=200; //细分区间 const double PI=3.14159265; const int INTERVAL=300; //决定振幅 int _tmain(int argc,_TCHAR* argv[]) { DWORD busySpan[COUNT]; DWORD idleSpan[COUNT]; 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; }
总结:
Sleep()——让当前线程停下来
WaitForSingleObject()——自己停下来,等待某个事情发生
GetTickCount()——得到系统启动到现在所经历的毫秒数
timeGetSystemTime()——另一种得到高精度时间的方法
GetProcessorInfo() / SetThreadAffinityMask() ——遇到多核用这两个方法更好控制CPU
GetCPUTickCount()——获取CPU核心运行周期,要配合上面两个方法来使用,否则得到的值没什么意义