通過程式設計控制CPU利用率

jeanron100發表於2015-03-09
今天想起一個幾年前學習過的程式,是在《程式設計之美》中提到的,是作為當時微軟的面試題,寫一個程式來控制CPU的利用率保持在50%,進一步延伸,能夠寫出程式來畫出CPU利用率的正弦曲線。
這個題目看起來真是奇怪,能夠達到這種程度,程式設計感覺就是出神入化了,但是仔細看看這個題目還是有一些依據可循,也有點小聰明的意思。
首先,對我們來說,能夠直觀感受CPU利用率就是通過工作管理員來得到的,我們可以大體的觀察得到,基本上重新整理CPU利用率的情況是按照秒來更新的,任何額外的操作都可能造成CPU的抖動,比如我開啟另外一個程式,或者動動滑鼠之類的。
所以在程式中,處理的時候CPU就開始忙起來了,如果想在一定的時間頻度內給予CPU空閒時間,使得CPU利用率保持在50%,就代表
(CPU忙碌/(CPU忙碌+CPU空閒)=50%
從程式中來實現,CPU忙碌可以通過迴圈來實現,而空閒則可以通過sleep來實現。
關於這個實現,自己使用瞭如下的程式碼

點選(此處)摺疊或開啟

  1. public class CPUTest 
  2. { 
  3.     public static void main(String[] args) 
  4.     { 
  5.         long startTime = 0; 
  6.         int busyTime = 10; 
  7.         int idleTime = 10;
  8.         while (true) 
  9.         { 
  10.             startTime = System.currentTimeMillis(); 
  11.             while (System.currentTimeMillis() - startTime <= busyTime) 
  12.                 try 
  13.             { 
  14.                 Thread.sleep(idleTime); 
  15.             } 
  16.             catch (InterruptedException e) 
  17.             { 
  18.                 e.printStackTrace(); 
  19.               }
  20.         } 
  21.     }
  22. }
這個程式來本地的環境中測試,因為是多CPU的,所以得到的結果總是不太滿意,沒有達到預期,在單核的情況是沒有問題的。
我靈機一動,可以通過Total CPU的使用率來說明。在工作管理員->效能 頁面的右下角,有個資源監控的按鈕,點進去就能看到一些詳細的資訊了。


得到了基本的要求,使得CPU利用率在50%左右,我們可以得到一個更為複雜的例子,就是畫出正弦曲線來。
這個例子在本地測試基本得到了預期的效果。
使用的程式碼如下:

點選(此處)摺疊或開啟

  1. public class CPUTest
  2. {
  3.    
  4.     
  5.     public static void main(String[] args) throws Exception {
  6.         final double SPLIT = 0.01;
  7.         final int COUNT = (int) (2 / SPLIT);
  8.         final double PI = Math.PI;
  9.         final int INTERVAL = 200;
  10.         long[] busySpan = new long[COUNT];
  11.         long[] idleSpan = new long[COUNT];
  12.         int half = INTERVAL / 2;
  13.         double radian = 0.0;
  14.         for (int i = 0; i < COUNT; i++) {
  15.           busySpan[i] = (long) (half + (Math.sin(PI * radian) * half));
  16.           idleSpan[i] = INTERVAL - busySpan[i];
  17.           radian += SPLIT;
  18.         }
  19.         long startTime = 0;
  20.         int j = 0;
  21.         while (true) {
  22.           j = j % COUNT;
  23.           startTime = System.currentTimeMillis();
  24.           while (System.currentTimeMillis() - startTime < busySpan[j])
  25.             ;
  26.           Thread.sleep(idleSpan[j]);
  27.           j++;
  28.         }
  29.       }
  30. }
得到的圖表如下,是不是有點味道。


可以通過這個例子看到,如果明白一些基本的知識點,結合實際還是能夠得到很多意想不到的效果,學以致用在這個時候還是挺有趣的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1454146/,如需轉載,請註明出處,否則將追究法律責任。

相關文章