编程之美 读书笔记1.1 让CPU占用率曲线听你指挥
本笔记是自我总结,如果有摘抄,会注明出处。本笔记可以在不侵害他人版权的情况下做非商业用途转载。商业用途请联系我 ^_^
原题不粘贴。
题目很简单,如果是单核单线程编程,也比较容易。只要调用windows.h中的GetTickTime()就可以实现了。
如果是多核多线程,比如我的电脑I3处理双核4线程,原题就要改进。
首先需要知道如何在c++中使用多线程。C++语言本身不支持多线程(应该说不是显式支持多线程,毕竟语言本身是不管编译器如何实现它自身的)。使用的是WINAPI 的CreateThread(),将需要运行的函数的指针传给CreateThread(),返回的是HANDLE 类。
接着通过 SetThreadAffinityMask(handle[i],ProcessAffinityMask[i])设置使用多核CPU的哪个核心。handle[i]对应的是生成的那个线程,ProcessAffinityMask[i]则代表核心对应的掩码。
我照着 雁过无痕 http://www.cppblog.com/flyinghearts/archive/2010/12/02/135311.html的程序输入了一遍,结果是这样的(无视那个眼睛护士吧--)
很诡异不是吗,为什么只有第3线程的线条看起来比较正确呢。仔细研究了一下,发现了一个BUG,
SetThreadAffinityMask(handle[i], i + 1);
哦,这个掩码肯定不能是从1到10这样简单的排列的。google了一下,
二进制00000001代表CPU1,二进制00000010代表CPU2,二进制00000100代表CPU3,以此类推。
于是我就重新改了程序
定义掩码查找数组:
const DWORD ProcessAffinityMask[]={
0x01,0x02,0x04,0x08
};
如果你有32核可以多写一点,0x16,0x32,。。。。
接着
SetThreadAffinityMask(handle[i],ProcessAffinityMask[i])
这样就对了!
额,你要问我为啥这么丑。。一个原因是参数优化的问题,资源管理器大概1s刷新一格,一div大概10个point,曲线的平滑性还和CPU的频率有很大关系,程序的时间粒要针对不同CPU的频率优化才行。还有这个程序只能控制自身占用cpu的时间,不能得到CPU的占用率(据说taskmgr用了一个不公开的API),后台其他程序也会影响CPU的占用率,所以这个sin存在许多波动,不可能平滑。可以用HOOK去获取CPU 占用率,不过这样程序就很复杂了。
思考:能不能让CPU不同核产生不同曲线?比如CPU1是直线,CPU2是sin,CPU3是sinx/x,等等。
顺便说下,原以为程序只产生4个线程,结果却是5个,原来main函数也会产生一个线程啊。
游戏人生的代码我觉得简单许多,不过他用的是SetProcessAffinityMask(),只产生一个曲线。http://www.cppblog.com/Fox/archive/2008/04/17/control_cpu_using_curve.html