写一个程序。让用户来决定Windows任务管理器(Task Manager)的CPU占用率(单核)。
有下面几种情况: 1.CPU占用率固定在50%,为一条直线 2.CPU的占用率为一条直线,详细占用率由命令行參数决定(范围1~100) 3.CPU的占用率状态为一条正弦曲线 4.多核处理器情况下上述问题怎么解决
一个刷新时间是多久,书上说,通过对任务管理器观測,大约是1秒。鼠标移动、后台程序等都会对曲线造成影响!
单核环境下。空死循环会导致100%的CPU占用率。双核环境下,CPU总占用率大约为50%。四核是25%左右。
我的cpu是 I5 2410M 2.30GHZ(双核四线程,如图) 由于眼下的cpu每一个时钟周期可运行两条以上的代码,取平均值2,于是(2300000000*2)/5=920000000(循环/秒) 每秒能够运行循环920000000次。
不能简单的取n=920000000然后sleep(1000)。假设让cpu工作1s,歇息1s非常可能是锯齿。先达到一个峰值然后跌入一个非常低的占有率。所以我们睡眠时间改为100ms。100ms比較接近windows的调度时间,n=92000000。假设sleep时间选的太小。会造成线程频繁的唤醒和挂起,无形中添加了内核时间的不确定性因此代码例如以下:
#include <windows.h> int main(void) { //Run on CPU 0(0x00000001)(00000001) //Run on CPU 1(0x00000002)(00000010) //Run on CPU 0 AND CPU 1(0x00000003)(00000101) //Run on CPU 2(0x00000004)(00000100) //...... //SetProcessAffinityMask(GetCurrentProcess(),0x1);//进程与指定cpu绑定 SetThreadAffinityMask(GetCurrentThread(), 0x1);//线程与指定cpu绑定 while(true) { for(int i=0;i<92000000;i++) ; Sleep(100); } return 0; }使用SetProcessAffinityMask函数。进程与CPU绑定。得到例如以下图。
使用SetThreadAffinityMask函数,进程与CPU绑定,得到例如以下图。
假设不考虑其他程序的CPU占用情况,能够在每一个核上开一个线程,执行指定的函数。实现每一个核的CPU占用率同样。假设CPU占用率曲线不是周期性变化,就要对每一个t值都要计算一次,否则,能够仅仅计算第一个周期内的各个t值。其他周期的直接取缓存计算结果。
#include<iostream> #include<cmath> #include<windows.h> static int PERIOD = 60 * 1000; //周期ms const int COUNT = 300; //一个周期计算次数 const double GAP_LINEAR = 100; //线性函数时间间隔100ms const double PI = 3.1415926535898; //PI const double GAP = (double)PERIOD / COUNT; //周期函数时间间隔 const double FACTOR = 2 * PI / PERIOD; //周期函数的系数 static double Ratio = 0.5; //线性函数的值 0.5即50% static double Max=0.9; //方波函数的最大值 static double Min=0.1; //方波函数的最小值 typedef double Func(double); //定义一个函数类型 Func*为函数指针 typedef void Solve(Func *calc);//定义函数类型,參数为函数指针Func* inline DWORD get_time() { return GetTickCount(); //操作系统启动到如今所经过的时间ms } double calc_sin(double x) //调用周期函数solve_period的參数 { return (1 + sin(FACTOR * x)) / 2; //y=1/2(1+sin(a*x)) } double calc_fangbo(double x) //调用周期函数solve_period的參数 { //方波函数 if(x<=PERIOD/2) return Max; else return Min; } void solve_period(Func *calc) //线程函数为周期函数 { double x = 0.0; double cache[COUNT]; for (int i = 0; i < COUNT; ++i, x += GAP) cache[i] = calc(x); int count = 0; while(1) { unsigned ta = get_time(); if (count >= COUNT) count = 0; double r = cache[count++]; DWORD busy = r * GAP; while(get_time() - ta < busy) {} Sleep(GAP - busy); } } void solve_linear(Func*) //线程函数为线性函数,參数为空 NULL { const unsigned BUSY = Ratio * GAP_LINEAR; const unsigned IDLE = (1 - Ratio) * GAP_LINEAR; while(1) { unsigned ta = get_time(); while(get_time() - ta < BUSY) {} Sleep(IDLE); } } void run(int i=1,double R=0.5,double T=60000,double max=0.9,double min=0.1) //i为输出状态,R为直线函数的值,T为周期函数的周期,max方波最大值,min方波最小值 { Ratio=R; PERIOD=T; Max=max; Min=min; Func *func[] = {NULL ,calc_sin,calc_fangbo}; //传给Solve的參数。函数指针数组 Solve *solve_func[] = { solve_linear, solve_period}; //Solve函数指针数组 SYSTEM_INFO info; GetSystemInfo(&info); //得到cpu数目 int NUM_CPUS = info.dwNumberOfProcessors; HANDLE *handle = new HANDLE[NUM_CPUS]; DWORD *thread_id = new DWORD[NUM_CPUS]; //线程id switch(i) { case 1: //cpu0 ,cpu1都输出直线 { for (int i = 0; i < NUM_CPUS; ++i) { Func *calc = func[0]; Solve *solve = solve_func[0]; if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve, (VOID*)calc, 0, &thread_id[i])) != NULL) //创建新线程 SetThreadAffinityMask(handle[i], i); //限定线程执行在哪个cpu上 } WaitForSingleObject(handle[0],INFINITE); //等待线程结束 break; } case 2: //cpu0直线,cpu1正弦 { if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[0], (VOID*)func[0], 0, &thread_id[1])) != NULL) //创建新线程 SetThreadAffinityMask(handle[1], 1); //限定线程执行在哪个cpu上 Func *calc = func[1]; Solve *solve = solve_func[1]; if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve, (VOID*)calc, 0, &thread_id[0])) != NULL) //创建新线程 SetThreadAffinityMask(handle[0], 2); //限定线程执行在哪个cpu上 WaitForSingleObject(handle[0],INFINITE); //等待线程结束 break; } case 3: //cpu0直线,cpu1方波 { if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[0], (VOID*)func[0], 0, &thread_id[0])) != NULL) //创建新线程 SetThreadAffinityMask(handle[0], 1); //限定线程执行在哪个cpu上 Func *calc = func[2]; Solve *solve = solve_func[1]; if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve, (VOID*)calc, 0, &thread_id[1])) != NULL) //创建新线程 SetThreadAffinityMask(handle[1], 2); //限定线程执行在哪个cpu上 WaitForSingleObject(handle[0],INFINITE); //等待线程结束 break; } case 4: //cpu0正弦。cpu1方波 { if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[1], (VOID*)func[1], 0, &thread_id[0])) != NULL) //创建新线程 SetThreadAffinityMask(handle[0], 1); //限定线程执行在哪个cpu上 Func *calc = func[2]; Solve *solve = solve_func[1]; if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve, (VOID*)calc, 0, &thread_id[1])) != NULL) //创建新线程 SetThreadAffinityMask(handle[1], 2); //限定线程执行在哪个cpu上 WaitForSingleObject(handle[0],INFINITE); //等待线程结束 break; } default: break; } } void main() { //run(1,0.5); //cpu1 ,cpu2都输出50%的直线 run(2,0.5,30000); //cpu1 0.5直线,cpu2正弦周期30000 //run(3); //cpu1直线,cpu2方波 //run(4,0.8,30000,0.95,0.5); //cpu1正弦。cpu2 0.95-0.5的方波 }这是是第一次CPU跑直线。第二个CPU跑正弦函数~~~~~~~~·
转载于:https://www.cnblogs.com/bhlsheji/p/5218188.html
相关资源:数据结构—成绩单生成器