• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Creative Commons License
            本Blog采用 知識共享署名-非商業性使用-禁止演繹 3.0 Unported許可協議 進行許可。 —— Fox <游戲人生>

            游戲人生

            游戲人生 != ( 人生 == 游戲 )
            站點遷移至:http://www.yulefox.com。請訂閱本博的朋友將RSS修改為http://feeds.feedburner.com/yulefox
            posts - 62, comments - 508, trackbacks - 0, articles - 7

            編程之美:讓CPU占用率曲線聽你指揮

            Posted on 2008-04-17 00:20 Fox 閱讀(11168) 評論(10)  編輯 收藏 引用 所屬分類: T技術碎語

            Author: Fox

            前兩天在買《計算機程序設計藝術》中文版的時候,偶然發現《編程之美》這本書,當時翻了一下,看到“讓CPU占用率曲線聽你指揮”這樣的題目確實讓人為之一動。寫一段代碼,可以讓CPU占有率曲線畫出平滑的正弦曲線,有點意思:-)。

            當然,最后沒有買這本書,雖然我可以肯定這是本好書。

            我從CSDN讀書上找到幾節,閑來讀一讀。今天來討論一下《讓CPU占用率曲線聽你指揮》。

            題目:寫一個程序,讓用戶來決定Windows任務管理器(Task Manager)的CPU占用率。程序越精簡越好,計算機語言不限。例如,可以實現下面三種情況:

            1.    CPU的占用率固定在50%,為一條直線;

            2.    CPU的占用率為一條直線,但是具體占用率由命令行參數決定(參數范圍1~ 100);

            3.    CPU的占用率狀態是一個正弦曲線。

            在討論具體實現之前,一個非常重要的問題是:什么是CPU占用率?

            編程之美》寫道:“在任務管理器的一個刷新周期內,CPU忙(執行應用程序)的時間和刷新周期總時間的比率,就是CPU的占用率,也就是說,任務管理器中顯示的是每個刷新周期內CPU占用率的統計平均值。

            打開“Windows 任務管理器”,“性能”中有“CPU使用記錄”一項,給出的就是CPU占有率曲線。

            至于一個刷新周期到底是多長,書中似乎沒有明確給出,只是說“大約是1秒鐘更新一次”,我打開Windows自帶的時鐘,也感覺大約是1秒鐘。

            另外的常識是:

            單核環境下,空死循環會導致100%的CPU占有率。雙核環境下,CPU總占有率大約為50%,四核會不會是25%左右呢?(我沒有四核,只能猜測了,估計各核間切換也會耗掉點時間,因為我的雙核環境并沒有出現一核100%,另一核空閑的情況)。

            當CPU整個刷新周期(絕大多數時間)空閑時,CPU占有率趨于0。

            書中給出的正弦實現如下:

            1 #include "Windows.h"
            2 #include "stdlib.h"
            3 #include "math.h" 
            4 
            5 const double SPLIT = 0.01;
            6 const int COUNT = 200;
            7 const double PI = 3.14159265;
            8 const int INTERVAL = 300;
            9 
            10 int _tmain(int argc, _TCHAR* argv[])
            11 {
            12     DWORD busySpan[COUNT];  //array of busy times
            13     DWORD idleSpan[COUNT];  //array of idle times
            14     int half = INTERVAL / 2;
            15     double radian = 0.0;
            16     for(int i = 0; i < COUNT; i++)
            17     {
            18         busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
            19         idleSpan[i] = INTERVAL - busySpan[i];
            20         radian += SPLIT;
            21     }
            22     DWORD startTime = 0;
            23     int j = 0;
            24     while (true)
            25     {
            26         j = j % COUNT;
            27         startTime = GetTickCount();
            28         while ((GetTickCount() - startTime) <= busySpan[j]) ;
            29         Sleep(idleSpan[j]);
            30         j++;
            31     }
            32     return 0;
            33 }


            在單核環境(P4 2.40)下,其表現還是不錯的:

            點擊查看大圖

            在雙核環境(Core2 E4500)下,就有點差強人意不盡人意了:

            點擊查看大圖

            不過,總還能看出是正弦曲線。

            上面兩圖的問題:

            1) 單核時曲線不夠平滑,是由于QQ等程序占用CPU所致;

            2) 雙核時曲線更加抖動,我的理解是除其他程序影響外,由于線程沒有固定運行在一個CPU上導致的,后面看到書上提到線程遷移,個人感覺這個叫法欠妥啊,總覺得線程遷移令人費解。

            可以立即想到的是:讓進程在指定處理器上運行(處理器親緣關系),由Windows提供了兩個API可以做到這一點:GetCurrentProcessSetProcessAffinityMask的。

            修改之后的代碼如下:

            1 #include "Windows.h"
            2 #include "stdlib.h"
            3 #include "math.h" 
            4 
            5 const double SPLIT = 0.01;
            6 const int COUNT = 200;
            7 const double PI = 3.14159265;
            8 const int INTERVAL = 300;
            9 
            10 int _tmain(int argc, _TCHAR* argv[])
            11 {
            12    SetProcessAffinityMask(
            13         GetCurrentProcess(),
            14         0x00000001          //cpu mask
            15         );
            16 
            17     DWORD busySpan[COUNT];  //array of busy times
            18     DWORD idleSpan[COUNT];  //array of idle times
            19     int half = INTERVAL / 2;
            20     double radian = 0.0;
            21     for(int i = 0; i < COUNT; i++)
            22     {
            23         busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
            24         idleSpan[i] = INTERVAL - busySpan[i];
            25         radian += SPLIT;
            26     }
            27     DWORD startTime = 0;
            28     int j = 0;
            29     while (true)
            30     {
            31         j = j % COUNT;
            32         startTime = GetTickCount();
            33         while ((GetTickCount() - startTime) <= busySpan[j]) ;
            34         Sleep(idleSpan[j]);
            35         j++;
            36     }
            37     return 0;
            38 }


            雙核環境(Core2 E4500)修改之后的輸出如下:

            點擊查看大圖

            我理想中的表現是:

            1) 曲線是平滑的,最好不因其他應用程序或操作的執行而改變;

            2) 不管是單核還是雙核,峰值皆為100%,谷值為0。

            對于第一點,其實就是保證任一刷新周期中的CPU占有率都可以被精確控制在0-100之間,如果你可以使CPU一直保持50%(而不是近似的上下波動),產生一條平滑的曲線就很easy了。

            問題的關鍵在于,除了當前你寫的程序可以控制,其他程序或操作如何控制?或者說:如何控制CPU的運行情況才是關鍵之處。

            PS: 一晚上老是斷網,搞得思路頻頻被打斷,興致也損了大半??傊?a target="_blank">編程之美》還是值得玩味一把吧:D。

            Feedback

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-17 12:17 by brent
            俺也看到這章了,

            看到題目的第一反應是設計一個反饋系統。

            看到解答挺失望的,感覺有點雕蟲小技的味道

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-17 21:02 by Fox
            恩,MS的面試題多如此類,翻一翻還是開闊思路

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-18 17:15 by Wang Feng
            unix上怎么辦?

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-18 18:29 by Fox
            @Wang Feng
            呵呵,MS的面試題啊:D

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-20 23:58 by greatws
            呵呵,不錯。
            不過我想到的是直接Hook任務管理器或者Hook查CPU利用率的API,可能會更精確

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-04-22 00:38 by www
            > 除了當前你寫的程序可以控制,其他程序或操作如何控制?

            書上也談到了一些。不過不是控制,而是“適應”。

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2008-06-28 00:40 by 不死阿三
            試過了,用c#改寫了一下,總是感覺不是很平滑。

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2009-03-29 01:00 by kg
            樓主,能不能解釋下,為什么要這樣設定:
            busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
            idleSpan[i] = INTERVAL - busySpan[i];

            為什么不可以這樣:
            busySpan[i] = (DWORD)(1 /2 + (sin(PI * radian) * 1 / 2));
            idleSpan[i] = 1- busySpan[i];
            這樣是不是CPU使用率=1/2*(1+sin(PI * radian))?

            liwenge21@sina.com,謝謝回復。

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2010-12-26 16:55 by lateCpp
            28 while ((GetTickCount() - startTime) <= busySpan[j]) ;
            29 Sleep(idleSpan[j]);

            ========================
            這個可以控制到sleep是正弦曲線嗎?
            我對WINDOWS API不太熟,大致理解是這樣:

            如果j=0時,busySpan[0]=150,相應的,IdleSpan[0]=150;
            如果j等某值時,busySpan[j]=180,相應的,IdleSpan[j]=120。(由計算公式,busySpan=150*(1+sin(j*pi)),可知,可以取到這個值,起碼近似。)

            這時候來看while循環(上面所引的行28):
            第一次循環:滿足<=180條件,執行一次Sleep(120);
            第二次循環:依然滿足<=180的條件 ,再執行一次Sleep(120);
            第三次循環:不滿足,跳出;
            這樣一共Sleep了240秒,顯然,這跟原來Sleep(IdleSpan[j])的初衷是不一致的。這個對產生的曲線應該也有影響吧?

            不知道理解的對不。希望交流討論。xueyayang AT gmail DOT com

            # re: 編程之美:讓CPU占用率曲線聽你指揮  回復  更多評論   

            2011-01-27 14:08 by BopGroup
            《編程之美》這在計劃修訂改版,歡迎大家提建議,這里(http://bop1.wikispaces.com/)有包含所有題目的wiki,大家可以注冊后提問,也可以直接給我發郵件 lispython@gmail.com。
            久久婷婷五月综合色99啪ak| 亚洲人成无码久久电影网站| 久久九九兔免费精品6| 无码乱码观看精品久久| 久久久久高潮综合影院| 久久免费的精品国产V∧| 一本大道加勒比久久综合| 久久免费99精品国产自在现线| 香蕉久久久久久狠狠色| 怡红院日本一道日本久久| 99久久精品免费看国产| 亚洲国产成人精品无码久久久久久综合 | 久久97久久97精品免视看秋霞| 久久久久久极精品久久久| 18岁日韩内射颜射午夜久久成人| 久久天堂电影网| 亚洲精品无码成人片久久| 久久综合九色综合久99| 久久久久亚洲AV片无码下载蜜桃| 国内精品久久人妻互换| 久久久久人妻一区精品| 成人资源影音先锋久久资源网| 亚洲国产精品综合久久网络 | 久久人人添人人爽添人人片牛牛 | 久久久精品久久久久影院| 国产精品久久久久久久| 久久人妻AV中文字幕| 久久黄视频| 国产叼嘿久久精品久久| 久久久久人妻一区二区三区vr| 久久本道综合久久伊人| 久久精品国产99国产电影网 | 香蕉久久夜色精品升级完成| 久久久久无码专区亚洲av| 久久国产精品一区二区| 国产精品视频久久久| 婷婷综合久久中文字幕蜜桃三电影| 日产久久强奸免费的看| 青青热久久国产久精品 | 色婷婷综合久久久久中文 | 青草影院天堂男人久久|