CPU利用率问题:操作系统原理和API

问题的提出:写一个程序,使得CPU的占用率可以听从用户的安排,第一种情况,CPU的占用率固定在50%,第二种情况,CPU的占用率为一条直线,具体占用率用参数表示;第三种情况,CPU的占用率状态是一条正弦曲线。

分析:这个问题,不了解操作系统原理和内核代码的人看起来很玄乎。但此问题的本质是操作系统原理,即操作系统如何分配资源给用户程序。进而分析到应用程序级别可得,CPU忙的时间和CPU休眠的时间相等时,根据刷新出来的图像便保持在50%左右。写应用程序,会用到Windows的API。

思路一:根据CPU的主频,计算每秒钟执行的指令条数,将循环用汇编代码表示,求得需要循环执行的次数。并且休眠同样的时间。

核心的API:Sleep()  

long GetCPUFreq()//获取CPU频率,单位: MHZ
{
	 int start1,start2;
	 _asm rdtsc
	 _asm mov start1,eax
	  Sleep(50);
	 _asm rdtsc
	 _asm mov start2,eax
	 return ((start2-start1)/50)/(1024);
}


//1-1
void SimpleCpu()
{
	while(true)
	{
		//busy
		for(int i=0;i<1181600000;i++)
			;
		//idle
		Sleep(10);
	}
}//simplecpu

思路二:使用GetTickCount()和Sleep()

使用GetTickCount获得系统启动以来的时间,然后根据需要休眠的时间确定忙循环要做的时间。

/GetTickCount和Sleep
void GetSleepCpu()
{
	const DWORD busyTime=100;	//10毫秒
	const DWORD idleTime=busyTime; //忙的时间和休眠的时间大致相当

	INT64 startTime=0;
	while(true)
	{
		DWORD startTime=GetTickCount();
		//bust loop
		while((GetTickCount()-startTime)<busyTime)
			;
		//idle loop
		Sleep(idleTime);
	}
}//GetSleepCpu

思路三:正弦曲线问题

把2Pi等分,计算振幅,然后让CPU工作在相应的振幅处。

void SineGraph()
{
	SetThreadAffinityMask(GetCurrentThread(), 1);   
	//将0-2Pi之间等分成200份进行抽样,计算每个抽样点的振幅
	//300ms是近似的值 6.28/200
	const int SAMPLINE_COUNT=200;	//抽样点数量
	const double PI=3.1415926535;	
	const int TOTAL_AMPLITUDE=300;	//每个抽样点对应的时间片

	DWORD busySpan[SAMPLINE_COUNT];	
	int apmlitude=TOTAL_AMPLITUDE;	
	double radian=0.0;
	double radianIncrement=(2.0*PI)/(double)SAMPLINE_COUNT;	//增量

	//计算每个抽样点的振幅
	for(int i=0;i<SAMPLINE_COUNT;i++)
	{
		busySpan[i]=(DWORD)(apmlitude+(sin(PI*radian)*apmlitude));
		radian+=radianIncrement;
	}

	DWORD startTime=0;
	for(int j=0;;j=(j+1)%SAMPLINE_COUNT)
	{
		startTime=GetTickCount();
		while((GetTickCount()-startTime)<=busySpan[j])
			;
		Sleep(TOTAL_AMPLITUDE-busySpan[j]);
	}

}//SineGraph

int _tmain(int argc, _TCHAR* argv[])
{
	int c;
	cin>>c;
	
	switch(c)
	{
	case 1:
		SimpleCpu();	//56%
		break;
	case 2:
		GetSleepCpu();	//51% 52%
		break;
	case 3:
		SineGraph();	//正弦曲线
		break;
	}
	return 0;
}

多核CPU的情况下,程序是不一样的写法,此处不讨论。这道题主要考察对操作系统的理解。

posted @ 2013-07-03 14:59  李VS超  阅读(1994)  评论(0编辑  收藏  举报