编程之美算是一本有趣的计算机书籍,上面说的东西也总能让我灰常灰常。。咳非常开心。所以我就整理一些出来吧。。
编程之美开篇的第一个问题就是让任务管理器里面的CPU占用率能够显示成正弦曲线或者恒定的某个值。
首先,我们假设单核的情况下,要让CPU变成100%再简单不过了,一个while(true)死循环即可,那么具体起来的原理呢?我们看到在循环开始的过程中,CPU占用率也不是瞬间飙满的,而是像实际的方波一样,有一个过渡.所以,任务管理器的CPu占有率表示的是,在一个刷新周期内(1s)CPU忙的时间和刷新时间的比值.所以我们只要在一个周期里面控制忙和空的比率即可.
那么,第一个任务就是50%,其实,按照编程之美上的写法似乎是可以做到的,但是麻烦的是处理执行的循环次数需要自己去试
自己试了几次发现,把进程的Affinity设置为CPU1会比CPU0 相对来说得到更加稳定一些的曲线。。
如果需要这样进行不断测试才能得到一条破直线,也太没意思了。所以就需要一些比较猛的办法。编程之美里面的一个解法用GetTickCount()函数来让程序在设定好的busytime里面执行循环。而另外一个根据适应力的方法是用PerformanceCounter对象来实时处理数据。但是原理都大同小异,本质都是计算时间比来调节。此外,书上那个C#的程序似乎还有探讨余地,我也不用C#,没有自己试。
编程之美里面给出的正弦曲线的代码:
正弦曲线:
这段代码还是和之前一样,不过就是把一段正弦曲线用划分为1/SPLIT段,也就是COUNT部分,每个部分的值用sin(PI*radian)算出来。
通过改变INTERVAL的值能够获得不同程度的单次时间,在图上的表现就是一个周期的时间不同了。
我的目标:
让双核CPU两个核的曲线呈相位差2/PI的正弦曲线
分析一下问题,其实和上面的正弦曲线没啥差别。但主要问题是多核CPU的时候需要使用多线程,并且分别给每个线程附加不同的循环。
对于双核的情况,要点在于将不同的线程附加到不同的核心上。这里需要了解ThreadAffinityMask的概念,这个mask值表示了不同的核心,虽然文档里面写的是从0开始的,但是我自己机器上貌似要1,2才有用。结果就如下图了。
期间用到了C++的多线程编程的概念。个人觉得这篇文章比较不错。
问题:
现在提出进一步的问题:怎么样在双核系统上只用一个进程(不能使用多线程/纤程)让两个CPU占用率都保持50%?
思路,能够控制系统的线程迁移?或者换个思路,把一个死循环按时间分别附加到不同的CPU核心上?