1.1 让CPU占用率曲线听你指挥[cpu manager]
【本文链接】
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; } |
【本文链接】