Interesting Programming - Controlling the CPU of your own computer

Keywords: Windows Programming

Topic 1: Write a program to show CPU occupancy in windows Task Manager as a sinusoidal function curve.

At first glance, I really don't have much idea about this topic. Because I haven't thought too much about performance and CPU usage. It's really a good application question after reading and searching materials. The following tasks will be completed step by step.

2. My operating environment:

Operating system: win 7 32 bits
CPU: Intel i7 2630 QM (2.0GHZ 4 core 8 threads)

III. Specific Realization

1. Multi-CPU Solutions


Because the program will show confusion under multi-CPU, code is needed to specify which CPU the program runs under.
The CPU can be specified using the Windows API with the following code:
  1. //Let the process run on the specified processor (on the first CPU, multi-CPU processing)  
  2.     SetProcessAffinityMask(  
  3.         GetCurrentProcess(),  
  4.         0x00000001          //cpu mask  
  5.          );  

2. The Idea of Controlling CPU


CPU has two states: busy and idle.
Control busy: Dead cycle.
Control leisure: sleep.
Windows Explorer: The CPU curve displayed is a recorded curve that records the current CPU occupancy and then draws the line slowly.

3. Control CPU by calculating CPU frequency

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "windows.h"  
  4. //To control the CPU, you need to calculate the CPU run time.  
  5. int main()  
  6. {  
  7.     //Let the process run on the specified processor (on the first CPU, multi-CPU processing)  
  8.     SetProcessAffinityMask(  
  9.         GetCurrentProcess(),  
  10.         0x00000001          //cpu mask  
  11.          );  
  12.       
  13.     for(;;)  
  14.     {  
  15.         //CPU 2.0GHZ 4 Core 8 Threads  
  16.         //Computing method: 9 power of 2.0*10, modern CPU can execute more than 2 codes per clock cycle  
  17.         //2000 000*2/5 = 800 000 000 000 000 average  
  18.         for(int i=0;i<8000000;i++)  
  19.         ;  
  20.         Sleep(10);//10ms is close to the schedule time slice of windows.  
  21.     }  
  22.       
  23.     //system("PAUSE");  
  24.     return 0;  
  25. }  
Operation effect:


As can be seen, the effect is not very good. Manual calculation must be inaccurate! And other programs also take up CPU.

4. Set the interval by GetTickCount() function


The advantage of doing this is that you don't need to estimate the CPU frequency, which is much better than the above method.

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "windows.h"  
  4. //Control CPU  
  5. int main()  
  6. {  
  7.     //Let the process run on the specified processor (on the first CPU, multi-CPU processing)  
  8.     SetProcessAffinityMask(  
  9.         GetCurrentProcess(),  
  10.         0x00000001          //cpu mask  
  11.          );  
  12.   
  13.     int busyTime = 100;  
  14.     int idleTime = busyTime;  
  15.     int start = 0;  
  16.     while(true)  
  17.     {  
  18.         //Estimation of CPU runtime is omitted with system function.  
  19.         start = GetTickCount();  
  20.         while((GetTickCount() - start) <= busyTime)  
  21.         ;  
  22.         //Leisure  
  23.         Sleep(idleTime);   
  24.     }   
  25.     //system("PAUSE");  
  26.     return 0;  
  27. }  
Effect:


Of course, the effect is general, paving the way for the following.

5. Drawing Sinusoidal Functions


To draw a sinusoidal curve, CPU busy time must increase slowly and then decrease. CPU idle time must be slowly decreasing and then increasing.

This is a cycle. The sinusoidal function curve is obtained by repeating the last straight cycle.

Print out part of the busy time relationship:



Code:
  1. #include <Windows.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <math.h>   
  5. #include <tchar.h>  
  6.   
  7. const double SPLIT = 0.01;  
  8. const int COUNT = 200;   
  9. const double PI = 3.14159265;  
  10. const int INTERVAL = 300;   //Interval time  
  11.   
  12. //Draw a sinusoidal curve.  
  13. int _tmain(int argc, _TCHAR* argv[])  
  14. {  
  15.     //Let the process run on the specified processor (on the first CPU, multi-CPU processing)  
  16.     SetProcessAffinityMask(  
  17.         GetCurrentProcess(),  
  18.         0x00000001          //cpu mask  
  19.          );  
  20.   
  21.     //1. Set up busy and idle time arrays  
  22.     DWORD busySpan[COUNT];  //array of busy times  
  23.     DWORD idleSpan[COUNT];  //array of idle times  
  24.     int half = INTERVAL / 2;  
  25.     double radian = 0.0;   //Radius  
  26.     for(int i = 0; i < COUNT; i++)  
  27.     {  
  28.         //The value range of sin(x) is [-1,1]. In order to display it completely, some parameter adjustments must be made to it.  
  29.         busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));  
  30.         idleSpan[i] = INTERVAL - busySpan[i];  
  31.         radian += SPLIT; //Add a little more each time.  
  32.     }  
  33.       
  34.     //Test: Output busy and idle time array, write to file result.txt  
  35.     FILE *fp;                    
  36.     fp = fopen("result.txt""a+");    //a + denotes additions  
  37.     for(int i = 0; i < COUNT; i++)  
  38.     {  
  39.        //printf("busySpan[%d] is %d\n",i,busySpan[i]);  
  40.        //printf("idleSpan[%d] is %d\n\n",i,idleSpan[i]);  
  41.         fprintf(fp, "busySpan[%d] is %d\n" , i, busySpan[i]);    
  42.         fprintf(fp, "idleSpan[%d] is %d\n\n" , i , idleSpan[i]);                      
  43.     }  
  44.     fclose(fp);  
  45.       
  46.   
  47.     //2. Drawing curves  
  48.     DWORD startTime = 0;          
  49.     int j = 0;  
  50.     while (true)  
  51.     {  
  52.         j = j % COUNT;    //COUNT is a cycle.  
  53.         startTime = GetTickCount();  
  54.         while ((GetTickCount() - startTime) <= busySpan[j])  
  55.         ;  
  56.         Sleep(idleSpan[j]);  
  57.         j++;  
  58.     }  
  59.       
  60.     return 0;  
  61. }  

Operation effect:


Changing the interval time INTERVAL = 100 can reduce the period accordingly:





For reprinting, please indicate the source: http://blog.csdn.net/xn4545945  

Reference to Beauty of Programming and Internet

Posted by ealderton on Mon, 17 Jun 2019 15:01:35 -0700