当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 24 篇帖子 ]  前往页数 1, 2  下一页
作者 内容
1 楼 
 文章标题 : 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-20 16:38 
头像

注册: 2009-04-18 11:41
帖子: 396
送出感谢: 0 次
接收感谢: 0 次
如题,我用python解决如下:
代码:
#!/usr/bin/env python
import itertools, math, time, sys

time_period = float(sys.argv[1]) if len(sys.argv) > 1 else 30   # seconds
time_slice  = float(sys.argv[2]) if len(sys.argv) > 2 else 0.04 # seconds

N = int(time_period / time_slice)
for i in itertools.cycle(range(N)):
    busy_time = time_slice / 2 * (math.sin(2*math.pi*i/N) + 1)
    t = time.clock() + busy_time
    while t > time.clock():
        pass
    time.sleep(time_slice - busy_time);


用c该怎么做呢?
还请大家集思广益~


_________________
重温经典,回归MUD
http://forum.ubuntu.org.cn/viewtopic.php?f=34&t=235277

我的博客,一些心得,欢迎分享哦
http://hi.baidu.com/rothsdad/home


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 20:09 
头像

注册: 2007-05-20 18:44
帖子: 438
地址: 唐山,河北,中国
送出感谢: 0 次
接收感谢: 1
什么意思啊?让CPU的负荷满足正弦曲线?


_________________
我逗无了奈了……
HP的本跑ubuntu还得把我折腾死。
显卡、无线/有线网卡、声卡、键盘……
代码:
while :
do
  work_hard
done


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 20:45 

注册: 2008-06-15 10:54
帖子: 75
送出感谢: 0 次
接收感谢: 0 次
楼主这是要干嘛? :em23


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 20:49 
头像

注册: 2009-04-18 11:41
帖子: 396
送出感谢: 0 次
接收感谢: 0 次
lonelycorn 写道:
什么意思啊?让CPU的负荷满足正弦曲线?


恩,差不多是这个意思。


_________________
重温经典,回归MUD
http://forum.ubuntu.org.cn/viewtopic.php?f=34&t=235277

我的博客,一些心得,欢迎分享哦
http://hi.baidu.com/rothsdad/home


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 20:53 
头像

注册: 2009-02-25 18:18
帖子: 2229
送出感谢: 0 次
接收感谢: 0 次
:em06


_________________
在中国搞IT的谁不知道Ctrl+C,Ctrl+V啊~


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 21:04 
头像

注册: 2009-04-18 11:41
帖子: 396
送出感谢: 0 次
接收感谢: 0 次
还是希望大家多动手思考一下~


_________________
重温经典,回归MUD
http://forum.ubuntu.org.cn/viewtopic.php?f=34&t=235277

我的博客,一些心得,欢迎分享哦
http://hi.baidu.com/rothsdad/home


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-21 22:34 
头像

注册: 2007-05-20 18:44
帖子: 438
地址: 唐山,河北,中国
送出感谢: 0 次
接收感谢: 1
不大可能吧,因为还有别的程序在运行。


_________________
我逗无了奈了……
HP的本跑ubuntu还得把我折腾死。
显卡、无线/有线网卡、声卡、键盘……
代码:
while :
do
  work_hard
done


页首
 用户资料  
 
8 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 0:57 

注册: 2006-09-07 22:51
帖子: 849
送出感谢: 0 次
接收感谢: 0 次
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <time.h>

#define mcrosec 1000000

double get_time(void)
{
   struct timeval tl;
   gettimeofday(&tl,NULL);
   return tl.tv_sec+tl.tv_usec*1.0/mcrosec;
}

int main(int argc,char **argv)
{
   double period ,slice;
   long N = 0,i = 1;
   double busy = 0,k = 0;
   double t = 0;
   if(argc>1){
      period = atof(argv[1]);
   }else{
      period = 30.0;
   }
   if(argc>2){
      slice = atof(argv[2]);
   }else{
      slice = 0.04;
   }
   N = period / slice;
   while(1){
      busy = slice /2.5 * (sin(2*M_PI*i/N) + 1);
      t = get_time() ;
      while (t + busy > k){
         k = get_time();
      }
      if(N<i){
         i = 0;
      }
      usleep((slice - busy)*mcrosec);
      i++;
      
   }
   return 0;
}


_________________
blog:http://wkt55555.blog.163.com/


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 2:25 
头像

注册: 2006-05-20 14:03
帖子: 898
送出感谢: 0 次
接收感谢: 0 次
这不是那个啥经典面试题么


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 6:19 
头像

注册: 2008-08-18 10:51
帖子: 415
地址: 北极北
送出感谢: 5
接收感谢: 0 次
引用:
http://book.csdn.net/bookfiles/656/10065620783.shtml

引用:
题目《让CPU占用率曲线听你指挥》
问题

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

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

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

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

分析与解法

有一名学生写了如下的代码:

while (true)

{

if (busy)

i++;

else

}

然后她就陷入了苦苦思索:else干什么呢?怎么才能让电脑不做事情呢?CPU使用率为0的时候,到底是什么东西在用CPU?另一名学生花了很多时间构想如何“深入内核,以控制CPU占用率”——可是事情真的有这么复杂么?

MSRA TTG(Microsoft Research Asia, Technology Transfer Group)的一些实习生写了各种解法,他们写的简单程序可以达到如图1-1所示的效果。



图1-1 编码控制CPU占用率呈现正弦曲线形态

看来这并不是不可能完成的任务。让我们仔细地回想一下写程序时曾经碰到的问题,如果我们不小心写了一个死循环,CPU占用率就会跳到最高,并且一直保持100%。我们也可以打开任务管理器,实际观测一下它是怎样变动的。凭肉眼观察,它大约是1秒钟更新一次。一般情况下,CPU使用率会很低。但是,当用户运行一个程序,执行一些复杂操作的时候,CPU的使用率会急剧升高。当用户晃动鼠标时,CPU的使用率也有小幅度的变化。

那当任务管理器报告CPU使用率为0的时候,谁在使用CPU呢?通过任务管理器的“进程(Process)”一栏可以看到,System Idle Process占用了CPU空闲的时间——这时候大家该回忆起在“操作系统原理”这门课上学到的一些知识了吧。系统中有那么多进程,它们什么时候能“闲下来”呢?答案很简单,这些程序或者在等待用户的输入,或者在等待某些事件的发生(WaitForSingleObject()),或者进入休眠状态(通过Sleep()来实现)。

在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率,也就是说,任务管理器中显示的是每个刷新周期内CPU占用率的统计平均值。因此,我们写一个程序,让它在任务管理器的刷新期间内一会儿忙,一会儿闲,然后通过调节忙/闲的比例,就可以控制任务管理器中显示的CPU占用率。

【解法一】简单的解法

步骤1 要操纵CPU的usage曲线,就需要使CPU在一段时间内(根据Task Manager的采样率)跑busy和idle两个不同的loop,从而通过不同的时间 比例,来获得调节CPU Usage的效果。

步骤2 Busy loop可以通过执行空循环来实现,idle可以通过Sleep()来实现。

问题的关键在于如何控制两个loop的时间,方法有二:

Sleep一段时间,然后以for循环n次,估算n的值。

那么对于一个空循环for(i = 0; i < n; i++);又该如何来估算这个最合适的n值呢?我们都知道CPU执行的是机器指令,而最接近于机器指令的语言是汇编语言,所以我们可以先把这个空循环简单地写成如下汇编代码后再进行分析:

loop:

mov dx i ;将i置入dx寄存器

inc dx ;将dx寄存器加1

mov i dx ;将dx中的值赋回i

cmp i n ;比较i和n

jl loop ;i小于n时则重复循环

假设这段代码要运行的CPU是P4 2.4Ghz(2.4 * 10的9次方个时钟周期每秒)。现代CPU每个时钟周期可以执行两条以上的代码,那么我们就取平均值两条,于是让(2 400 000 000 * 2)/5=960 000 000(循环/秒),也就是说CPU 1秒钟可以运行这个空循环960 000 000次。不过我们还是不能简单地将n = 60 000 000,然后Sleep(1000)了事。如果我们让CPU工作1秒钟,然后休息1秒钟,波形很有可能就是锯齿状的——先达到一个峰值(大于>50%),然后跌到一个很低的占用率。

我们尝试着降低两个数量级,令n = 9 600 000,而睡眠时间相应改为10毫秒(Sleep(10))。用10毫秒是因为它不大也不小,比较接近Windows的调度时间片。如果选得太小(比如1毫秒),则会造成线程频繁地被唤醒和挂起,无形中又增加了内核时间的不确定性影响。最后我们可以得到如下代码:

代码清单1-1

int main()

{

for(;;)

{

for(int i = 0; i < 9600000; i++);

Sleep(10);

}

return 0;

}

在不断调整9 600 000的参数后,我们就可以在一台指定的机器上获得一条大致稳定的50% CPU占用率直线。

使用这种方法要注意两点影响:

1. 尽量减少sleep/awake的频率,如果频繁发生,影响则会很大,因为此时优先级更高的操作系统内核调度程序会占用很多CPU运算时间。

2. 尽量不要调用system call(比如I/O这些privilege instruction),因为它也会导致很多不可控的内核运行时间。

该方法的缺点也很明显:不能适应机器差异性。一旦换了一个CPU,我们又得重新估算n值。有没有办法动态地了解CPU的运算能力,然后自动调节忙/闲的时间比呢?请看下一个解法。

【解法二】使用GetTickCount()和Sleep()

我们知道GetTickCount()可以得到“系统启动到现在”的毫秒值,最多能够统计到49.7天。另外,利用Sleep()函数,最多也只能精确到1毫秒。因此,可以在“毫秒”这个量级做操作和比较。具体如下:

利用GetTickCount()来实现busy loop的循环,用Sleep()实现idle loop。伪代码如下:

代码清单1-2

int busyTime = 10; //10 ms

int idleTime = busyTime; //same ratio will lead to 50% cpu usage

Int64 startTime = 0;

while (true)

{

startTime = GetTickCount();

// busy loop的循环

while ((GetTickCount() - startTime) <= busyTime) ;

//idle loop

Sleep(idleTime);

}

这两种解法都是假设目前系统上只有当前程序在运行,但实际上,操作系统中有很多程序都会在不同时间执行各种各样的任务,如果此刻其他进程使用了10% 的CPU,那我们的程序应该只能使用40%的CPU(而不是机械地占用50%),这样可达到50%的效果。

怎么做呢?

我们得知道“当前CPU占用率是多少”,这就要用到另一个工具来帮忙——Perfmon.exe。

Perfmon是从Windows NT开始就包含在Windows服务器和台式机操作系统的管理工具组中的专业监视工具之一(如图1-2所示)。Perfmon可监视各类系统计数器,获取有关操作系统、应用程序和硬件的统计数字。Perfmon的用法相当直接,只要选择您所要监视的对象(比如:处理器、RAM或硬盘),然后选择所要监视的计数器(比如监视物理磁盘对象时的平均队列长度)即可。还可以选择所要监视的实例,比如面对一台多CPU服务器时,可以选择监视特定的处理器。



图1-2 系统监视器(Perfmon)

我们可以写程序来查询Perfmon的值,Microsoft .Net Framework提供了PerformanceCounter()这一类型,从而可以方便地拿到当前各种计算机性能数据,包括CPU的使用率。例如下面这个程序——

【解法三】能动态适应的解法

代码清单1-3

//C# code

static void MakeUsage(float level)

{

PerformanceCounter p = new PerformanceCounter("Processor", "% Processor Time", "_Total");

while (true)

{

if (p.NextValue() > level)

System.Threading.Thread.Sleep(10);

}

}

可以看到,上面的解法能方便地处理各种CPU使用率参数。这个程序可以解答前面提到的问题2。

有了前面的积累,我们应该可以让任务管理器画出优美的正弦曲线了,见下面的代码。

【解法四】正弦曲线

代码清单1-4

//C++ code to make task manager generate sine graph

#include "Windows.h"

#include "stdlib.h"

#include "math.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]; //array of busy times

DWORD idleSpan[COUNT]; //array of idle times

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;

}
讨论

如果机器是多CPU,上面的程序会出现什么结果?如何在多个CPU时显示同样的状态?例如,在双核的机器上,如果让一个单线程的程序死循环,能让两个CPU的使用率达到50%的水平么?为什么?

多CPU的问题首先需要获得系统的CPU信息。可以使用GetProcessorInfo()获得多处理器的信息,然后指定进程在哪一个处理器上运行。其中指定运行使用的是SetThreadAffinityMask()函数。

另外,还可以使用RDTSC指令获取当前CPU核心运行周期数。

在x86平台上定义函数:

inline __int64 GetCPUTickCount()

{

__asm

{

rdtsc;

}

}

在x64平台上定义:

#define GetCPUTickCount() __rdtsc()

使用CallNtPowerInformation API得到CPU频率,从而将周期数转化为毫秒数,例如:

代码清单1-5

_PROCESSOR_POWER_INFORMATION info;

CallNTPowerInformation(11, //query processor power information

NULL, //no input buffer

0, //input buffer size is zero

&info, //output buffer

Sizeof(info)); //outbuf size

__int64 t_begin = GetCPUTickCount();

//do something

__int64 t_end = GetCPUTickCount();

double millisec = ((double)t_end –

(double)t_begin)/(double)info.CurrentMhz;

RDTSC指令读取当前CPU的周期数,在多CPU系统中,这个周期数在不同的CPU之间基数不同,频率也有可能不同。用从两个不同的CPU得到的周期数作计算会得出没有意义的值。如果线程在运行中被调度到了不同的CPU,就会出现上述情况。可用SetThreadAffinityMask避免线程迁移。另外,CPU的频率会随系统供电及负荷情况有所调整。
总结

能帮助你了解当前线程/进程/系统效能的API大致有以下这些:

1. Sleep()——这个方法能让当前线程“停”下来。

2. WaitForSingleObject()——自己停下来,等待某个事件发生

3. GetTickCount()——有人把Tick翻译成“嘀嗒”,很形象。

4. QueryPerformanceFrequency()、QueryPerformanceCounter()——让你访问到精度更高的CPU数据。

5. timeGetSystemTime()——是另一个得到高精度时间的方法。

6. PerformanceCounter——效能计数器。

7. GetProcessorInfo()/SetThreadAffinityMask()。遇到多核的问题怎么办呢?这两个方法能够帮你更好地控制CPU。

8. GetCPUTickCount()。想拿到CPU核心运行周期数吗?用用这个方法吧。


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 13:25 
头像

注册: 2009-04-18 11:41
帖子: 396
送出感谢: 0 次
接收感谢: 0 次
sphinx 写道:
引用:
http://book.csdn.net/bookfiles/656/10065620783.shtml

引用:
题目《让CPU占用率曲线听你指挥》
问题

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

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

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

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

分析与解法

有一名学生写了如下的代码:

while (true)

{

if (busy)

i++;

else

}

然后她就陷入了苦苦思索:else干什么呢?怎么才能让电脑不做事情呢?CPU使用率为0的时候,到底是什么东西在用CPU?另一名学生花了很多时间构想如何“深入内核,以控制CPU占用率”——可是事情真的有这么复杂么?

MSRA TTG(Microsoft Research Asia, Technology Transfer Group)的一些实习生写了各种解法,他们写的简单程序可以达到如图1-1所示的效果。



图1-1 编码控制CPU占用率呈现正弦曲线形态

看来这并不是不可能完成的任务。让我们仔细地回想一下写程序时曾经碰到的问题,如果我们不小心写了一个死循环,CPU占用率就会跳到最高,并且一直保持100%。我们也可以打开任务管理器,实际观测一下它是怎样变动的。凭肉眼观察,它大约是1秒钟更新一次。一般情况下,CPU使用率会很低。但是,当用户运行一个程序,执行一些复杂操作的时候,CPU的使用率会急剧升高。当用户晃动鼠标时,CPU的使用率也有小幅度的变化。

那当任务管理器报告CPU使用率为0的时候,谁在使用CPU呢?通过任务管理器的“进程(Process)”一栏可以看到,System Idle Process占用了CPU空闲的时间——这时候大家该回忆起在“操作系统原理”这门课上学到的一些知识了吧。系统中有那么多进程,它们什么时候能“闲下来”呢?答案很简单,这些程序或者在等待用户的输入,或者在等待某些事件的发生(WaitForSingleObject()),或者进入休眠状态(通过Sleep()来实现)。

在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率,也就是说,任务管理器中显示的是每个刷新周期内CPU占用率的统计平均值。因此,我们写一个程序,让它在任务管理器的刷新期间内一会儿忙,一会儿闲,然后通过调节忙/闲的比例,就可以控制任务管理器中显示的CPU占用率。

【解法一】简单的解法

步骤1 要操纵CPU的usage曲线,就需要使CPU在一段时间内(根据Task Manager的采样率)跑busy和idle两个不同的loop,从而通过不同的时间 比例,来获得调节CPU Usage的效果。

步骤2 Busy loop可以通过执行空循环来实现,idle可以通过Sleep()来实现。

问题的关键在于如何控制两个loop的时间,方法有二:

Sleep一段时间,然后以for循环n次,估算n的值。

那么对于一个空循环for(i = 0; i < n; i++);又该如何来估算这个最合适的n值呢?我们都知道CPU执行的是机器指令,而最接近于机器指令的语言是汇编语言,所以我们可以先把这个空循环简单地写成如下汇编代码后再进行分析:

loop:

mov dx i ;将i置入dx寄存器

inc dx ;将dx寄存器加1

mov i dx ;将dx中的值赋回i

cmp i n ;比较i和n

jl loop ;i小于n时则重复循环

假设这段代码要运行的CPU是P4 2.4Ghz(2.4 * 10的9次方个时钟周期每秒)。现代CPU每个时钟周期可以执行两条以上的代码,那么我们就取平均值两条,于是让(2 400 000 000 * 2)/5=960 000 000(循环/秒),也就是说CPU 1秒钟可以运行这个空循环960 000 000次。不过我们还是不能简单地将n = 60 000 000,然后Sleep(1000)了事。如果我们让CPU工作1秒钟,然后休息1秒钟,波形很有可能就是锯齿状的——先达到一个峰值(大于>50%),然后跌到一个很低的占用率。

我们尝试着降低两个数量级,令n = 9 600 000,而睡眠时间相应改为10毫秒(Sleep(10))。用10毫秒是因为它不大也不小,比较接近Windows的调度时间片。如果选得太小(比如1毫秒),则会造成线程频繁地被唤醒和挂起,无形中又增加了内核时间的不确定性影响。最后我们可以得到如下代码:

代码清单1-1

int main()

{

for(;;)

{

for(int i = 0; i < 9600000; i++);

Sleep(10);

}

return 0;

}

在不断调整9 600 000的参数后,我们就可以在一台指定的机器上获得一条大致稳定的50% CPU占用率直线。

使用这种方法要注意两点影响:

1. 尽量减少sleep/awake的频率,如果频繁发生,影响则会很大,因为此时优先级更高的操作系统内核调度程序会占用很多CPU运算时间。

2. 尽量不要调用system call(比如I/O这些privilege instruction),因为它也会导致很多不可控的内核运行时间。

该方法的缺点也很明显:不能适应机器差异性。一旦换了一个CPU,我们又得重新估算n值。有没有办法动态地了解CPU的运算能力,然后自动调节忙/闲的时间比呢?请看下一个解法。

【解法二】使用GetTickCount()和Sleep()

我们知道GetTickCount()可以得到“系统启动到现在”的毫秒值,最多能够统计到49.7天。另外,利用Sleep()函数,最多也只能精确到1毫秒。因此,可以在“毫秒”这个量级做操作和比较。具体如下:

利用GetTickCount()来实现busy loop的循环,用Sleep()实现idle loop。伪代码如下:

代码清单1-2

int busyTime = 10; //10 ms

int idleTime = busyTime; //same ratio will lead to 50% cpu usage

Int64 startTime = 0;

while (true)

{

startTime = GetTickCount();

// busy loop的循环

while ((GetTickCount() - startTime) <= busyTime) ;

//idle loop

Sleep(idleTime);

}

这两种解法都是假设目前系统上只有当前程序在运行,但实际上,操作系统中有很多程序都会在不同时间执行各种各样的任务,如果此刻其他进程使用了10% 的CPU,那我们的程序应该只能使用40%的CPU(而不是机械地占用50%),这样可达到50%的效果。

怎么做呢?

我们得知道“当前CPU占用率是多少”,这就要用到另一个工具来帮忙——Perfmon.exe。

Perfmon是从Windows NT开始就包含在Windows服务器和台式机操作系统的管理工具组中的专业监视工具之一(如图1-2所示)。Perfmon可监视各类系统计数器,获取有关操作系统、应用程序和硬件的统计数字。Perfmon的用法相当直接,只要选择您所要监视的对象(比如:处理器、RAM或硬盘),然后选择所要监视的计数器(比如监视物理磁盘对象时的平均队列长度)即可。还可以选择所要监视的实例,比如面对一台多CPU服务器时,可以选择监视特定的处理器。



图1-2 系统监视器(Perfmon)

我们可以写程序来查询Perfmon的值,Microsoft .Net Framework提供了PerformanceCounter()这一类型,从而可以方便地拿到当前各种计算机性能数据,包括CPU的使用率。例如下面这个程序——

【解法三】能动态适应的解法

代码清单1-3

//C# code

static void MakeUsage(float level)

{

PerformanceCounter p = new PerformanceCounter("Processor", "% Processor Time", "_Total");

while (true)

{

if (p.NextValue() > level)

System.Threading.Thread.Sleep(10);

}

}

可以看到,上面的解法能方便地处理各种CPU使用率参数。这个程序可以解答前面提到的问题2。

有了前面的积累,我们应该可以让任务管理器画出优美的正弦曲线了,见下面的代码。

【解法四】正弦曲线

代码清单1-4

//C++ code to make task manager generate sine graph

#include "Windows.h"

#include "stdlib.h"

#include "math.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]; //array of busy times

DWORD idleSpan[COUNT]; //array of idle times

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;

}
讨论

如果机器是多CPU,上面的程序会出现什么结果?如何在多个CPU时显示同样的状态?例如,在双核的机器上,如果让一个单线程的程序死循环,能让两个CPU的使用率达到50%的水平么?为什么?

多CPU的问题首先需要获得系统的CPU信息。可以使用GetProcessorInfo()获得多处理器的信息,然后指定进程在哪一个处理器上运行。其中指定运行使用的是SetThreadAffinityMask()函数。

另外,还可以使用RDTSC指令获取当前CPU核心运行周期数。

在x86平台上定义函数:

inline __int64 GetCPUTickCount()

{

__asm

{

rdtsc;

}

}

在x64平台上定义:

#define GetCPUTickCount() __rdtsc()

使用CallNtPowerInformation API得到CPU频率,从而将周期数转化为毫秒数,例如:

代码清单1-5

_PROCESSOR_POWER_INFORMATION info;

CallNTPowerInformation(11, //query processor power information

NULL, //no input buffer

0, //input buffer size is zero

&info, //output buffer

Sizeof(info)); //outbuf size

__int64 t_begin = GetCPUTickCount();

//do something

__int64 t_end = GetCPUTickCount();

double millisec = ((double)t_end –

(double)t_begin)/(double)info.CurrentMhz;

RDTSC指令读取当前CPU的周期数,在多CPU系统中,这个周期数在不同的CPU之间基数不同,频率也有可能不同。用从两个不同的CPU得到的周期数作计算会得出没有意义的值。如果线程在运行中被调度到了不同的CPU,就会出现上述情况。可用SetThreadAffinityMask避免线程迁移。另外,CPU的频率会随系统供电及负荷情况有所调整。
总结

能帮助你了解当前线程/进程/系统效能的API大致有以下这些:

1. Sleep()——这个方法能让当前线程“停”下来。

2. WaitForSingleObject()——自己停下来,等待某个事件发生

3. GetTickCount()——有人把Tick翻译成“嘀嗒”,很形象。

4. QueryPerformanceFrequency()、QueryPerformanceCounter()——让你访问到精度更高的CPU数据。

5. timeGetSystemTime()——是另一个得到高精度时间的方法。

6. PerformanceCounter——效能计数器。

7. GetProcessorInfo()/SetThreadAffinityMask()。遇到多核的问题怎么办呢?这两个方法能够帮你更好地控制CPU。

8. GetCPUTickCount()。想拿到CPU核心运行周期数吗?用用这个方法吧。


m$的东东,windows的API, linux上应该用自己的方法实现。


_________________
重温经典,回归MUD
http://forum.ubuntu.org.cn/viewtopic.php?f=34&t=235277

我的博客,一些心得,欢迎分享哦
http://hi.baidu.com/rothsdad/home


页首
 用户资料  
 
12 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 18:53 

注册: 2006-09-07 22:51
帖子: 849
送出感谢: 0 次
接收感谢: 0 次
lonelycorn 写道:
不大可能吧,因为还有别的程序在运行。

附件:
.jpg


_________________
blog:http://wkt55555.blog.163.com/


页首
 用户资料  
 
13 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 21:59 
头像

注册: 2006-04-12 20:05
帖子: 8495
地址: 杭州
送出感谢: 0 次
接收感谢: 8
这需求估计也只能在面试的时候用到吧~呵呵..


_________________
关注我的blog: ε==3


页首
 用户资料  
 
14 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-05-22 22:01 
头像

注册: 2007-05-20 18:44
帖子: 438
地址: 唐山,河北,中国
送出感谢: 0 次
接收感谢: 1
这连两个周期都不到。


_________________
我逗无了奈了……
HP的本跑ubuntu还得把我折腾死。
显卡、无线/有线网卡、声卡、键盘……
代码:
while :
do
  work_hard
done


页首
 用户资料  
 
15 楼 
 文章标题 : Re: 如何让cpu呈现优美的正弦曲线呢?
帖子发表于 : 2009-07-03 22:55 
头像

注册: 2008-11-23 16:04
帖子: 19
送出感谢: 0 次
接收感谢: 0 次
还是比较强的~~~


_________________
AMD 4400+
AMD R770+SB600/ONDA A770S
ATI HD2600PRO/DATALAND


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 24 篇帖子 ]  前往页数 1, 2  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译