通過程式設計控制CPU利用率(r4筆記第69天)
阿新 • • 發佈:2022-05-04
今天想起一個幾年前學習過的程式,是在《程式設計之美》中提到的,是作為當時微軟的面試題,寫一個程式來控制CPU的利用率保持在50%,進一步延伸,能夠寫出程式來畫出CPU利用率的正弦曲線。 這個題目看起來真是奇怪,能夠達到這種程度,程式設計感覺就是出神入化了,但是仔細看看這個題目還是有一些依據可循,也有點小聰明的意思。 首先,對我們來說,能夠直觀感受CPU利用率就是通過工作管理員來得到的,我們可以大體的觀察得到,基本上重新整理CPU利用率的情況是按照秒來更新的,任何額外的操作都可能造成CPU的抖動,比如我開啟另外一個程式,或者動動滑鼠之類的。 所以在程式中,處理的時候CPU就開始忙起來了,如果想在一定的時間頻度內給予CPU空閒時間,使得CPU利用率保持在50%,就代表 (CPU忙碌/(CPU忙碌+CPU空閒)=50% 從程式中來實現,CPU忙碌可以通過迴圈來實現,而空閒則可以通過sleep來實現。 關於這個實現,自己使用瞭如下的程式碼
public class CPUTest { public static void main(String[] args) { long startTime = 0; int busyTime = 10; int idleTime = 10; while (true) { startTime = System.currentTimeMillis(); while (System.currentTimeMillis() - startTime <= busyTime) try { Thread.sleep(idleTime); } catch (InterruptedException e) { e.printStackTrace(); } } } }
這個程式來本地的環境中測試,因為是多CPU的,所以得到的結果總是不太滿意,沒有達到預期,在單核的情況是沒有問題的。 我靈機一動,可以通過Total CPU的使用率來說明。在工作管理員->效能 頁面的右下角,有個資源監控的按鈕,點進去就能看到一些詳細的資訊了。
得到了基本的要求,使得CPU利用率在50%左右,我們可以得到一個更為複雜的例子,就是畫出正弦曲線來。 這個例子在本地測試基本得到了預期的效果。 使用的程式碼如下:
public class CPUTest { public static void main(String[] args) throws Exception { final double SPLIT = 0.01; final int COUNT = (int) (2 / SPLIT); final double PI = Math.PI; final int INTERVAL = 200; long[] busySpan = new long[COUNT]; long[] idleSpan = new long[COUNT]; int half = INTERVAL / 2; double radian = 0.0; for (int i = 0; i < COUNT; i++) { busySpan[i] = (long) (half + (Math.sin(PI * radian) * half)); idleSpan[i] = INTERVAL - busySpan[i]; radian += SPLIT; } long startTime = 0; int j = 0; while (true) { j = j % COUNT; startTime = System.currentTimeMillis(); while (System.currentTimeMillis() - startTime < busySpan[j]) ; Thread.sleep(idleSpan[j]); j++; } } }
得到的圖表如下,是不是有點味道。
可以通過這個例子看到,如果明白一些基本的知識點,結合實際還是能夠得到很多意想不到的效果,學以致用在這個時候還是挺有趣的。