收藏 分享(赏)

task manager.pdf

上传人:李静文 文档编号:5912 上传时间:2018-05-21 格式:PDF 页数:8 大小:536.59KB
下载 相关 举报
task manager.pdf_第1页
第1页 / 共8页
task manager.pdf_第2页
第2页 / 共8页
task manager.pdf_第3页
第3页 / 共8页
task manager.pdf_第4页
第4页 / 共8页
task manager.pdf_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、1.1 让 CPU 占用率曲线听你指挥 编程之美微软技术面试心得 1 编程之美微软技术面试心得 编程之美微软技术面试心得 (http:/www.china- ) 是微软亚洲研 究 院 技术创新 组 研发主管 邹 欣继移 山 之道VSTS 软件开发 指南后 的 最新力作 。 它传达 给读者 :微 软 重视什 么样 的 能力, 需要 什 么样的 人才 。 但它更 深层 的 意义在 于引 导 读者思 考, 提 倡一种发 现问题、 解决问题的思维方式, 充分挖掘编程的乐趣, 展示编程之美。 本书3 月 份 上 市 。 网上讨论和解答 在: 题目让 CPU 占用率曲线听你指挥 问题 写一个程序,让用户来

2、决定 Windows 任务管理器(Task Manager )的 CPU 占用率。程 序越精简越好,计算机语言不限。例如,可以实现下面三种情况: 1. CPU 的占用率固定在50% ,为一条直线; 2. CPU 的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1 100 ) ; 1.1 让 CPU 占用率曲线听你指挥 编程之美微软技术面试心得 2 3. CPU 的占用率状态是一个正弦曲线。 分析与解法 1有一名学生写了如下的代码: while (true) if (busy) i+ ; else 然后她就陷入了苦苦思索: else 干什 么呢?怎么才能让电脑不做事情呢?CPU 使用

3、率为 0 的时候, 到底是什么东西在用 CPU ?另一名学生花了很多时间构想如何“深入内核,以控 制 CPU 占用率”可是事情真的有这么复杂么? MSRA TTG (Microsoft Research Asia, Technology Transfer Group )的一些实 习生写了各 种解法,他们写的简单程序可以达到如图 1-1 所 示的效果。 图1-1 编码控制 CPU 占用率呈现正弦曲线形态 看来这并不是不可能完成的任务。 让我们仔细地回想一下写程序时曾经碰到的问题, 如1 作者注 : 当面 试的同学听到这 个问题的时候 , 很多人都有点意 外。 我把我的 笔 记本电脑交给他 们说,

4、 这 是 开 卷考试,你可以 上网查资料,干 什么都可以。大 部分面试者在电 脑上的第一个动 作就是上网搜索 “CPU 控 制 50% ”这样 的关键字,当然 没有找到什么直 接的结果。不过 这本书出版以后 ,情况可能就不 一样了。 1.1 让 CPU 占用率曲线听你指挥 编程之美微软技术面试心得 3 果我们不小心写了一个死循环,CPU 占用率就会跳到最高, 并且一直保持 100% 。 我们也可 以打开任务管理器 2 ,实际观测一下它是怎样变动的。凭肉眼观察,它大约是 1 秒钟更新一 次。一 般情 况下,CPU 使 用 率会 很低 。 但是 ,当 用户 运行一 个程 序,执 行一 些复杂 操作

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

6、务管理器的一个刷新周期内,CPU 忙(执行应用程序)的时间和刷新周期总时间的 比率,就是 CPU 的占用率,也就是说,任务管理器中显示的是每个刷新周期内 CPU 占用率 的统计平均值。因此,我们写一个程序,让它在任务管理器的刷新期间内一会儿忙,一会儿 闲,然后通过调节忙/ 闲的比例,就可以控制任务管理器中显示的 CPU 占用率。 【解法一】简单的解法 步骤 1 要操纵 CPU 的 usage 曲线,就需要使 CPU 在一段时间内(根据 Task Manager 的 采样率)跑 busy 和 idle 两个不同的 loop ,从而通 过不同的时间比例,来获得调节 CPU Usage 的效果 。

7、步骤 2 Busy loop 可 以通过执行空循环来实现,idle 可以 通过Sleep() 来实现。 问题的关键在于如何控制两个 loop 的时间,方法有二: Sleep 一段时 间,然后以for 循环n 次,估算n 的值。 那么对于一个空循环 for(i = 0; i 50% ) , 然后跌到一个很低的占用率。 我们尝试着降低两个数量级,令 n = 9 600 000 ,而睡眠时间相应改为 10 毫秒 (Sleep(10) ) 。用 10 毫 秒是因为它不大也不小, 比较接近 Windows 的 调度时间片。 如果 选 得太小(比如 1 毫秒) ,则会造成线程频繁地被唤醒和挂起,无形中又增

8、加了内核时间的不 确定性影响。最后我们可以得到如下代码: 代码清单 1-1 int main() for(;) for(int i = 0; i level) System.Threading.Thread.Sleep(10); 可以看到,上面的解法能方便地处理各种 CPU 使用率参数。这个程序可以解答前面提 到的问题 2 。 有了前面的积累,我们应该可以让任务管理器画出优美的正弦曲线了,见下面的代码。 【解法四】正弦曲线 代码清单 1-4 /C+ code to make task manager generate sine graph #include “Windows.h“ #inclu

9、de “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 busySpanCOUNT; /array of busy times DWORD idleSpanCOUNT; /array of idle times int half = INTERVAL / 2; double radian = 0.

10、0; for(int i = 0; i COUNT; i+) busySpani = (DWORD)(half + (sin(PI * radian) * half); idleSpani = INTERVAL - busySpani; radian += SPLIT; DWORD startTime = 0; int j = 0; while (true) j = j % COUNT; startTime = GetTickCount(); while (GetTickCount() - startTime) = busySpanj) ; Sleep(idleSpanj); j+; retu

11、rn 0; 1.1 让 CPU 占用率曲线听你指挥 编程之美微软技术面试心得 7 讨论 如果机器是 多 CPU ,上面的程序会 出现什么结 果?如何在 多个 CPU 时显示同样 的 状 态?例如,在双核的机器上,如果让一个单线程的程序死循环,能让两个 CPU 的 使用率达 到 50% 的水 平么?为什么? 多 CPU 的问 题首先需要获得系统的 CPU 信息。 可以使用 GetProcessorInfo() 获得多 处理器的信息, 然后指定进程在哪一个处理器上运行。其中指定运行使用的是 SetThreadAffinityMask() 函数。 另外,还可以使用 RDTSC 指令获取 当前 CPU

12、 核心运行周期数。 在 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 bu

13、ffer 0, /input buffer size is zero /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 得 到的周期数作计算会得出没有意

14、 义的值。如果线程在运行中被调度到了不同的 CPU ,就会出现上述情况。可用 SetThreadAffinityMask 避 免线程迁移。 另外, CPU 的频率会随系统供电及负荷情况有所调整。 总结 能帮助你了解当前线程/ 进程/ 系统效能的 API 大致有以下这些: 1.1 让 CPU 占用率曲线听你指挥 编程之美微软技术面试心得 8 1. Sleep() 这个方法能让当前线程“停”下来。 2. WaitForSingleObject() 自己停下来,等待某个事件发生 3. GetTickCount() 有人把Tick 翻译 成“嘀嗒”,很 形象。 4. QueryPerformanceFrequency() 、QueryPerformanceCounter() 让你访问到精 度更高的 CPU 数据。 5. timeGetSystemTime() 是另一个得到高精度时间的方法。 6. PerformanceCounter 效能计数器。 7. GetProcessorInfo()/SetThreadAffinityMask() 。 遇到多核的问题怎么办呢?这两 个方法能够帮你更好地控制 CPU 。 8. GetCPUTickCount() 。想拿到 CPU 核心运行周期数吗?用用这个方法吧。 了解并应用了上面的 API ,就可以考虑在简历中写上“精通 Windows ”了。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 网络技术 > 热门技术

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报