降低 CPU 佔用率的方法
CPU 佔用率和什麼有關?
答:1.單位時間內執行的指令數目多少(使用者時間);2.I/O操作時間(等待時間);3.執行緒排程花費的時間(軟/硬中斷、優先順序調整時間)。
舉個例子:
好比一個大人,每次來回可以扛一袋大米,每天的任務要求扛 60 袋,假定來回的路程花費的時間為 10 分鐘,如果要全速完成(不存在休息),那麼需要 10 小時,如果我們選擇 10 小時為單位,那麼在這個時間段內跑了 60 個不帶休息的來回(100% 佔用);如果我們每次來回允許其休息 10 分鐘(執行時間 Exec(10),休息時間Sleep(10)),那麼平均的 CPU 佔用就會在 50%,但是如果高精度繪製 CPU 佔用曲線圖,會發現 CPU 實際上是 10 分鐘 100%,10 分鐘 0%,如何平均——即把 Sleep(10) 穿插到 Exec(10) 中?
結論1:通過掛起執行緒去減少每個/單個執行緒單位時間內連續執行的使用者指令數目,是降低 CPU 佔用的最好途徑,但弊端是:導致任務完成的延期。
例子2:
每天要扛 600 袋米,顯然一個大人是扛不完了,所以我們要僱傭 10 個人,每個人到了扛米的地方,先用手機打個電話通知大家,剩餘幾袋,需不需要再派人來扛(WaitForSingleObject,等待“需要扛米通知”的訊號量,實際上就是為了保護,公共變數臨界區同時被多個執行緒訪問所導致的錯誤)?收到通知後(第一個人/執行緒扛了米,變數恢復到無執行緒訪問,此時可以解鎖臨界區並且選取第二個執行緒去訪問),在第一個人扛米剛準備回來時,第二個人去扛米,當然到了扛米地點也要打電話通知大家!如此一來,仍然是一天就能完成 600 袋米的作業量。
結論2:
在多核處理器中,多執行緒技術明顯的提高了系統的吞吐量,平均了每個核的 CPU 佔用率,但是需要話費較小的管理時間為代價:多個執行緒競爭 CPU 資源,每次誰可以競爭成功就是如何排程所要花費的時間,而一個任務被邏輯上的分派給不同的執行緒,但實際上還是位於公共區,就會帶來為了防止併發訪問資源帶來的衝突新增等待訊號的時間代價。
注意:對於單核處理器,多執行緒技術不見得會降低 CPU 佔用率,反而會增加佔用率,虛擬出來的人手可能導致 CPU 超負荷運轉。
例子3:
剛才那 10 個人,每個人都去扛米,但是工頭不放心,不斷地打電話問詢剩餘米的數目,導致效率低小,CPU 佔用提高。
結論:在迴圈中,任務的執行是有條件的,那麼這個條件語句最好不是非同步的,而是阻塞的,這樣可以降低 CPU 佔用率。
總結:
降低CPU的佔用率,基本就是不要用while(1) 空轉,用訊息、通知等配合多執行緒在多核處理中的作用;如果有些任務只有跳進成熟才會被執行,比如單獨一個執行緒接收 socket 資料,收到後解析,那麼條件收到資料就不要用非同步方式不停判斷返回值,而是使用同步阻塞的方式