1- <!DOCTYPE html>
2- < html lang ="en ">
3- < head >
4- < meta charset ="UTF-8 " />
5- < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
6- < title > CPU Load Generator</ title >
7-
8- <!-- lightweight, self‑contained styling -->
9- < style >
10- : root {
11- --accent : # 0069d9 ;
12- --bg : # f7f9fc ;
13- --text : # 222 ;
14- --code-bg : # eee ;
15- }
16- * { box-sizing : border-box; }
17- body {
18- margin : 0 ;
19- font-family : system-ui, -apple-system, "Segoe UI" , Roboto, sans-serif;
20- line-height : 1.6 ;
21- color : var (--text );
22- background : var (--bg );
23- }
24- header {
25- background : var (--accent );
26- color : # fff ;
27- padding : 2rem 1rem ;
28- text-align : center;
29- }
30- header h1 { margin : 0 0 .25rem ; font-size : 2.25rem ; }
31- header a { color : # fff ; font-weight : 600 ; text-decoration : underline; }
32- main {
33- max-width : 58rem ;
34- margin : 2rem auto;
35- padding : 0 1rem ;
36- }
37- section {
38- background : # fff ;
39- padding : 2rem 1.5rem ;
40- border-radius : .85rem ;
41- box-shadow : 0 2px 6px rgba (0 , 0 , 0 , .08 );
42- margin-bottom : 2rem ;
43- }
44- h2 { margin-top : 0 ; color : var (--accent ); }
45- h3 , h4 { color : var (--accent ); margin-bottom : .25rem ; }
46- img { max-width : 100% ; height : auto; border-radius : .5rem ; }
47- ul { padding-left : 1.25rem ; }
48- pre , code {
49- font-family : ui-monospace, "SFMono-Regular" , Consolas, monospace;
50- background : var (--code-bg );
51- border-radius : .35rem ;
52- }
53- pre { padding : .75rem 1rem ; overflow-x : auto; }
54- footer {
55- text-align : center;
56- padding : 1rem ;
57- font-size : .9rem ;
58- color : # 666 ;
59- }
60- </ style >
61- </ head >
62- < body >
1+ ---
2+ layout: default # use the layout that ships with jekyll-theme-minimal
3+ title: CPU Load Generator # appears in the < title > tag and navbar (if any)
4+ ---
5+
6+ <!-- lightweight, self‑contained styling -->
7+ < style >
8+ : root {
9+ --accent : # 0069d9 ;
10+ --bg : # f7f9fc ;
11+ --text : # 222 ;
12+ --code-bg : # eee ;
13+ }
14+ * { box-sizing : border-box; }
15+ body {
16+ margin : 0 ;
17+ font-family : system-ui, -apple-system, "Segoe UI" , Roboto, sans-serif;
18+ line-height : 1.6 ;
19+ color : var (--text );
20+ background : var (--bg );
21+ }
22+ header {
23+ background : var (--accent );
24+ color : # fff ;
25+ padding : 2rem 1rem ;
26+ text-align : center;
27+ }
28+ header h1 { margin : 0 0 .25rem ; font-size : 2.25rem ; }
29+ header a { color : # fff ; font-weight : 600 ; text-decoration : underline; }
30+ main {
31+ max-width : 58rem ;
32+ margin : 2rem auto;
33+ padding : 0 1rem ;
34+ }
35+ section {
36+ background : # fff ;
37+ padding : 2rem 1.5rem ;
38+ border-radius : .85rem ;
39+ box-shadow : 0 2px 6px rgba (0 , 0 , 0 , .08 );
40+ margin-bottom : 2rem ;
41+ }
42+ h2 { margin-top : 0 ; color : var (--accent ); }
43+ h3 , h4 { color : var (--accent ); margin-bottom : .25rem ; }
44+ img { max-width : 100% ; height : auto; border-radius : .5rem ; }
45+ ul { padding-left : 1.25rem ; }
46+ pre , code {
47+ font-family : ui-monospace, "SFMono-Regular" , Consolas, monospace;
48+ background : var (--code-bg );
49+ border-radius : .35rem ;
50+ }
51+ pre { padding : .75rem 1rem ; overflow-x : auto; }
52+ footer {
53+ text-align : center;
54+ padding : 1rem ;
55+ font-size : .9rem ;
56+ color : # 666 ;
57+ }
58+ </ style >
6359
6460<!-- ===== Hero ===== -->
6561< header >
@@ -70,8 +66,8 @@ <h1>CPU Load Generator</h1>
7066 target ="_blank " rel ="noopener "> View the project on GitHub ↗︎</ a >
7167 </ p >
7268</ header >
73- < main >
7469
70+ < main >
7571 <!-- ===== Motivation ===== -->
7672 < section id ="motivation ">
7773 < h2 > Motivation</ h2 >
@@ -80,114 +76,46 @@ <h2>Motivation</h2>
8076 < strong > stable CPU load for a finite period</ strong > by closing the loop with a PID regulator.
8177 </ p >
8278 < ul >
83- < li >
84- < strong > Performance testing: </ strong >
85- Stress‑test applications and full systems to uncover bottlenecks and verify robustness under load.
86- </ li >
87- < li >
88- < strong > Resource‑allocation optimisation: </ strong >
89- Reproduce real‑world utilisation scenarios so you can fine‑tune CPU quotas and scheduling policies.
90- </ li >
91- < li >
92- < strong > Benchmarking: </ strong >
93- Generate a consistent, repeatable workload that makes it easy to compare CPUs, machines, or configurations.
94- </ li >
95- < li >
96- < strong > Education & training: </ strong >
97- Give students hands‑on experience with discrete PID control and demonstrate how load impacts performance.
98- </ li >
99- < li >
100- < strong > Thermal / power analysis: </ strong >
101- Investigate heat dissipation and energy consumption under a controlled, steady workload.
102- </ li >
79+ < li > < strong > Performance testing: </ strong > Stress‑test applications and full systems to uncover bottlenecks and verify robustness under load.</ li >
80+ < li > < strong > Resource‑allocation optimisation: </ strong > Reproduce real‑world utilisation scenarios so you can fine‑tune CPU quotas and scheduling policies.</ li >
81+ < li > < strong > Benchmarking: </ strong > Generate a consistent, repeatable workload that makes it easy to compare CPUs, machines, or configurations.</ li >
82+ < li > < strong > Education & training: </ strong > Give students hands‑on experience with discrete PID control and demonstrate how load impacts performance.</ li >
83+ < li > < strong > Thermal / power analysis: </ strong > Investigate heat dissipation and energy consumption under a controlled, steady workload.</ li >
10384 </ ul >
10485 </ section >
10586
106- <!-- ===== PID Regulator ===== -->
107- < section id ="pid ">
108- < h2 > PID regulator for controlling CPU load</ h2 >
109- < img src ="https://gaetanocarlucci.altervista.org/wp-content/uploads/2024/07/pid-1.png "
110- alt ="PID control diagram " loading ="lazy ">
111- < p >
112- The architecture uses two threads: a < em > Monitor Thread</ em > that measures CPU
113- utilisation and a < em > Controller Thread</ em > that applies PI control to adjust
114- the sleep time of a tight loop so the measured load matches the
115- target.
116- </ p >
87+ <!-- ===== PID Regulator ===== -->
88+ < section id ="pid ">
89+ < h2 > PID regulator for controlling CPU load</ h2 >
90+ < img src ="https://gaetanocarlucci.altervista.org/wp-content/uploads/2024/07/pid-1.png "
91+ alt ="PID control diagram " loading ="lazy ">
92+ < p >
93+ The architecture uses two threads: a < em > Monitor Thread</ em > that measures CPU
94+ utilisation and a < em > Controller Thread</ em > that applies PI control to adjust
95+ the sleep time of a tight loop so the measured load matches the
96+ target.
97+ </ p >
11798
118- < h3 > Monitor Thread</ h3 >
119- < p >
120- Samples CPU usage at a fixed interval via
121- < code > psutil.cpu_percent(interval)</ code > , filters the measurements with a
122- first‑order filter and logs the results.
123- </ p >
99+ < h3 > Monitor Thread</ h3 >
100+ < p >
101+ Samples CPU usage at a fixed interval via
102+ < code > psutil.cpu_percent(interval)</ code > , filters the measurements with a
103+ first‑order filter and logs the results.
104+ </ p >
124105
125- < h3 > Controller Thread</ h3 >
126- < p >
127- Compares the target load (< em > set‑point</ em > ) and actual load, then computes the
128- control signal using proportional (< code > K< sub > p</ sub > </ code > ) and integral
129- (< code > K< sub > i</ sub > </ code > ) actions. The derivative term is not used.
130- </ p >
106+ < h3 > Controller Thread</ h3 >
107+ < p >
108+ Compares the target load (< em > set‑point</ em > ) and actual load, then computes the
109+ control signal using proportional (< code > K< sub > p</ sub > </ code > ) and integral
110+ (< code > K< sub > i</ sub > </ code > ) actions. The derivative term is not used.
111+ </ p >
131112
132- < pre > < code > # actuator snippet
113+ ```python
114+ # actuator snippet
133115def generate_load(self, sleep_time):
134116 interval = time.time() + self.period - sleep_time
135- while time.time() < interval:
117+ while time.time() < interval:
136118 pr = 213123 # busy‑work
137119 _ = pr * pr
138120 pr = pr + 1
139- time.sleep(sleep_time)</ code > </ pre >
140-
141- < pre > < code > # main PI control loop
142- def run(self):
143- def cpu_model(cpu_period):
144- return self.period - cpu_period # maps period to sleep time
145-
146- self.shutdown_flag.clear()
147- while not self.shutdown_flag.is_set():
148- time.sleep(self.sampling_interval)
149-
150- with self.target_lock, self.cpu_lock:
151- CT = self.CT # target load
152- cpu = self.cpu # measured load
153-
154- self.err = CT - cpu * 0.01
155- ts = time.time()
156- samp_int = ts - self.last_ts
157- self.int_err += self.err * samp_int
158- self.last_ts = ts
159- self.cpuPeriod = (self.kp * self.err +
160- self.ki * self.int_err)
161-
162- # anti‑windup
163- self.cpuPeriod = max(0, min(self.cpuPeriod, self.period))
164- self.set_sleep_time(cpu_model(self.cpuPeriod))</ code > </ pre >
165-
166- < h3 > PI tuning insights</ h3 >
167- < p >
168- Raising < code > K< sub > p</ sub > </ code > speeds up the response but risks overshoot; adding an
169- integral term removes steady‑state error at the cost of sluggishness
170- and potential oscillations, so anti‑windup is essential.
171- </ p >
172- </ section >
173-
174- <!-- ===== Results ===== -->
175- < section id ="results ">
176- < h2 > Results</ h2 >
177- < p >
178- Quick test in a GitHub Codespace or local shell:
179- < code > ./CPULoadGenerator.py -c 0 -c 3 -l 0.55 -l 0.12</ code >
180- </ p >
181-
182- < p > Example 50 % target load on core 0 for 20 s:</ p >
183- < img src ="https://gaetanocarlucci.altervista.org/wp-content/uploads/2024/07/50-Target-Load.png "
184- alt ="CPU‑load plot " loading ="lazy ">
185- </ section >
186-
187- </ main >
188-
189- < footer >
190- MIT License • © 2025 Gaetano Carlucci
191- </ footer >
192- </ body >
193- </ html >
121+ time.sleep(sleep_time)
0 commit comments