• 编程之美1 让CPU占用率曲线听你指挥


    Tag:Windows

    题目

    写一个程序,让用户决定Windows任务管理器(Task Manager)的CPU占用率。例如,可以实现下面三种情况:

    1. CPU的占用率固定在50%,为一条直线;
    2. CPU的占用率为一条直线,具体占用率由命令行参数决定(参数范围1-100);
    3. CPU的占用率状态是一个正弦曲线

    思路与算法

    观察我们的任务管理器,可以发现:
    大约是1秒钟更新一次,一般情况下,使用率都很低,当用户运行一个程序,执行复杂操作时,cpu的使用率会急剧升高。
    通过查阅资料可以知道:

    在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率。

    问题一、二

    1.想要操作CPU的使用率曲线,就需要使CPU在一段时间内跑busy和idle两个不同的循环。
    对于一个空循环for(i = 0; i < n; i++)如何估算最合适的n值?
    需要查阅资料:

    假设这段代码要运行的CPU是P4 2.4Ghz(2.4 * 10 的9次方个时钟周期每秒)现代CPU每个时钟周期可以执行两条以上的代码,我们取平均值两条,CPU一秒钟可以运行空循环 2.4 * 10的9次方*2次。
    我们可以使n低于这个数字,比如n = 9600000,sleep(10).

    代码:

    int main() {
    	for(;;) {
    		for(int i = 0; i < 9600000; i++) {
    			;
    		sleep(10);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    **缺点:**不能适应机器差异性

    1. 使用getTickCount和sleep
    int busyTime = 10;
    int idleTime = busyTime;
    Int64 startTime = 0;
    while(true) {
    	startTime = GetTickCount();
    	while((GetTickCount() - startTime) <= busyTime) 
    		;
    	sleep(idleTime);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    缺点:都是假设只有当前程序在运行

    1. 使用perfmon.exe

    perfrom是Windows管理工具组中的专业检测工具之一,可以获取有关操作系统、应用程序和硬件的各种效能计数器,画正弦曲线:

    double split = 0.01;
    int count = 200;
    double pi = 3.14159265;
    int interval = 300;
    
    int main() {
    	int[] busySpan[count];
    	idlSpan[count];
    	int half = intrnal / 2;
    	double radian = 0.0;
    	for(int i = 0; i < count; i++) {
    		busySpan[i] = (half + (sin(pi * radian) * half));
    		idleSpan[i] = interval - busySpan[i];
    		radian += split;
    	}
    	startTime = 0;
    	int j = 0;
    	while(true) {
    		j = j % count;
    		startTime = GetTickCount();
    		while((GetTickCount() - startTime) <= busySpan[j])
    			;
    		sleep(idleSpan[j]);
    		j++;
    	}
    	reteurn 0;
    }
    
    • 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

    问题三

    想要让cpu的使用率成为一条正弦曲线,可以把一条正弦曲线0~2π之间的弧度等分成200份进行抽样,计算每个抽样点的振幅,然后每隔一段时间(例如300ms)取下一个抽样点,并让cpu工作对应振幅的时间。

    代码

    package arithmetic;
    
    import java.math.BigDecimal;
    import java.text.DecimalFormat;
    import java.util.*;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    class drawSin implements Runnable {
        public void run() {
            final double SPLIT = 0.01;
            final int COUNT = (int)(2 / SPLIT);
            final double PI = Math.PI;
            final int interval = 100;
            long[] busy = new long[COUNT];
            long[] idle = new long[COUNT];
            int half = interval / 2;
            double x = 0.0;
            for(int i = 0; i < COUNT; i++) {
                busy[i] = (long)(half + (Math.sin(PI * x) * half))/ 2;
                idle[i] = interval - busy[i];
                x += SPLIT;
            }
            long start = 0;
            int j = 0;
            while (true) {
                j = j % COUNT;
                start = System.currentTimeMillis();
                while(System.currentTimeMillis() - start < busy[j]) ;
                try {
                    Thread.sleep(idle[j]);
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
                j++;
            }
        }
    }
    public class Main {
        public static void main(String[] args) throws Exception {
           Runtime runtime = Runtime.getRuntime();
           ExecutorService executorService = Executors.newFixedThreadPool(runtime.availableProcessors());
            for (int i = 0; i < runtime.availableProcessors(); i++){//每个核心都上一个线程
                executorService.execute(new drawSin());
            }
            executorService.shutdown();
        }
    }
    
    • 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
  • 相关阅读:
    C#.Net筑基-基础知识
    java计算机毕业设计ssm金华学校社团管理系统
    JavaScript中的短路表达式
    cannot find -lmysqlclient 错误解决
    基于java+ssm的在线投票管理系统-计算机毕业设计
    java基础
    JVM-Java虚拟机内存区域
    Hmmer安装与使用-Hmmer-3.3.2(bioinfomatics tools-009)
    适用于 .NET 的现代化、流畅、可测试的HTTP客户端库
    新零售SaaS架构:客户管理系统架构设计(万字图文总结)
  • 原文地址:https://blog.csdn.net/qq_41380950/article/details/127970317