【本文鏈接】
http://www.cnblogs.com/hellogiser/p/cpu-manager.html
【題目】
寫一個程序,讓用戶來決定Windows任務管理器(Task Manager)的CPU占用率。程序越精簡越好,計算機語言不限。例如,可以實現下面三種情況:
1. CPU的占用率固定在50%,為一條直線;
2. CPU的占用率為一條直線,但是具體占用率由命令行參數決定(參數范圍1~ 100);
3. CPU的占用率狀態是一個正弦曲線。
【分析】
如果不考慮其它程序的CPU占用情況,可以在每個核上開一個線程,運行指定的函數,實現每個核的CPU占用率相同。
要讓CPU的占用率,呈函數 y = calc(t) (0 <= y <= 1, t為時間,單位為ms )分布,只要取間隔很短的一系列點,認為在某個間隔內,y值近似不變。
設間隔值為GAP,顯然在指定t值附近的GAP這段時間內,
CPU占用時間為:busy = GAP * calc(t),
CPU空閑時間為:idle = GAP – busy
(1)對於CPU的占用率固定在50%,cacl(t)返回一個常數值0.5;
(2)對於CPU的占用率固定在p%,cacl(t)返回一個常數值p/100;
(3) CPU的占用率狀態是一個正弦曲線,則y = 0.5 * (1 + sin(a * t + b))
其周期T = 2 * PI / a (PI = 3.1415927),可以指定T值為60s即60000ms,則可以確定a值為 2 * PI / T, 若在這60000ms內我們計算200次(c = 200),則GAP值為 T / c = 300ms.也就是說,只要確定了周期和計算次數,其它幾個參數也都確定下來。
可以創建一個線程,然后在指定的處理器上運行。具體可以通過CreateThread,SetThreadAffinityMask和WaitForSingleObject函數來實現。
【代碼】
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
// 01_CPUManager.cpp : Defines the entry point for the console application. // /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/24 */ #include "stdafx.h" #include <cmath> #include <iostream> #include <Windows.h> using namespace std; #define GAP_LINEAR 100 #define RATIO 0 . 5 typedef double Func( double ); double cacl_linear( double ratio) { return ratio; } void Solve_Linear(Func *cacl) { unsigned BUSY_TIME = GAP_LINEAR * cacl(RATIO); //ms unsigned IDLE_TIME = GAP_LINEAR - BUSY_TIME; //ms INT64 startTime = 0 ; while ( true ) { //busy loop startTime = GetTickCount(); while (GetTickCount() - startTime < BUSY_TIME) ; // idle loop Sleep(IDLE_TIME); } } void Run_Linear() { // run on processor 1 HANDLE handle; DWORD thread_id; handle = CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)Solve_Linear, (VOID *)cacl_linear, 0 , &thread_id); if (handle != NULL ) SetThreadAffinityMask(handle, 1 ); // run on process #1 WaitForSingleObject(handle, INFINITE); } /* y = calc(t) (0 <= y <= 1) GAP busy: GAP*calc(t) idle: GAP-busy y = 0.5 * (1 + sin(a * t + b)) */ const int PERIOD = 60 * 1000 ; // ms const int COUNT = 200 ; const double GAP = ( double )PERIOD / COUNT; const double PI = 3 . 1415926 ; const double A = ( 2 * PI) / PERIOD; double cacl_sin( double t) { // t = 0,1*gap,2*gap,...,200*gap return ( 1 + sin(A * t)) / 2 ; } void Solve_Sin(Func *cacl) { double BUSY_TIME[COUNT] ; //ms double t = 0 . 0 ; for ( int i = 0 ; i < COUNT; ++i) { t = i * GAP; BUSY_TIME[i] = GAP * cacl(t); } int i = 0 ; INT64 startTime = 0 ; unsigned busyTime, idleTime; while ( true ) { if (i >= COUNT) i = 0 ; busyTime = BUSY_TIME[i]; idleTime = GAP - busyTime; //busy loop startTime = GetTickCount(); while (GetTickCount() - startTime < busyTime) ; // idle loop Sleep(idleTime); } } void Run_Sin() { // run on processor 2 HANDLE handle; DWORD thread_id; handle = CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)Solve_Sin, (VOID *)cacl_sin, 0 , &thread_id); if (handle != NULL ) SetThreadAffinityMask(handle, 2 ); // run on process #2 WaitForSingleObject(handle, INFINITE); } void test_main() { Run_Linear(); Run_Sin(); } int _tmain( int argc, _TCHAR *argv[]) { test_main(); return 0 ; } |
【本文鏈接】