CPU占用率:所谓CPU占用率就是在任务管理器的一个刷新周期内,CPU执行应用程序的事件和刷新周期总时间的比率。在任务管理器中显示的是每个刷新周期的CPU占用率的统计平均值。
自定义CPU占用率曲线即是写一个程序控制CPU的执行时间与休息时间,(此处应当注意是单核还是多核)。
busy loop即是忙碌时间,可以写一个空循环进行占用CPU;
idle loop即是休闲时间,可以使用sheep函数进行实现;
简单解法
假设CPU为2.4GHz(2.4*10的9次方个时钟周期每秒 ),现代CPU的每个时钟周期可以执行两条以上的代码,我们取值平均为2条,于是(2400 000 000*2)/5=960 000 000(循环/秒)由于理解尚不深刻此处暂时理解整个程序的代码为5行 也就是说CPU一秒钟可以执行960 000 000次
此处可以将CPU运行一秒休息一秒 即是
n=960 000 000 sleep(1000)
但是此种方法会让CPU的占用率呈锯齿状-----先达到一个峰值(>50%),然后跌到一个很低的占用率
于是我们可以将数据降低两个数量级,令n=960 000 0;sleep(10)。此处使用10毫秒而不是1毫秒的原因是10毫秒比较接近Windows的调度时间片。如果选的太小比如1毫秒的话会造成线程的频繁唤醒和挂起,无形之中会增加内核时间的不确定性。
最后代码为:
时钟周期是由CPU时钟定义的定长时间间隔,是CPU工作的最小时间单位,也称节拍脉冲或T周期。 时钟周期表示了SDRAM所能运行的最高频率。 ... 对于PC100规格的内存来说,它的运行时钟周期应该不高于10纳秒。
使用GetTickCount()和Sleep()
使用GetTickCount()函数可以得到“系统启动到现在”所经历的毫秒值,最多能够统计到49.7天
int busyTime = 10;//定义忙碌时间为10毫秒
int idleTime = busyTime;//定义相同的时间
int startTime = 0;//定义判断忙碌与空闲时间区域的开始点
while(true){
statTime = GetTickCount();//获取本次开始的时间
while((GetTickCount()-startTime)<=busyTime) //此处为判断忙碌时间区域是否达到预定的时间
;//空执行代码用来占用CPU使用率
Sheep(idleTime);//CPU休眠是时间
}
上述两种解法都是默认当前系统上只有当前程序运行
能动态适应的解法
此处使用了C#代码(由于博主还未学习c#故目前只有这些注释 以后会适时进行更新)
using System;
using System.Diagnostics;
namespace cpu
{
class Program
{
static void Main(string[] args)
{
cpu(0.5);
}
static void cpu(double level)
{
PerformanceCounter p = new PerformanceCounter("Processor", "% Processor Time", "_Total");
if (p == null)
{
return;
}
while (true)
{
if (p.NextValue() > level)
System.Threading.Thread.Sleep(10);
}
}
}
}
正弦曲线
此处使用的是c++代码
#include
#include
int main(void)
{
SetThreadAffinityMask(GetCurrentProcess(), 0x00000001);
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 { 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]) //比较当前所经历的cpu占用时间是否超过了设定的cpu占用时间,若未达到则进行空循环的cpu占用,若超过则进行设定好的休眠时间 ; Sleep(idleSpan[j]); //休眠代码 j++; } return 0; } DWORD为无符号类型,在Windows下经常用来保存地址或存放指针,在头文件Windows下
此处只是考虑了部分特殊情况 还有多种未知的情况 尚未讨论