Skip to content

Commit d14623f

Browse files
Update index.html
1 parent 2cce826 commit d14623f

File tree

1 file changed

+91
-163
lines changed

1 file changed

+91
-163
lines changed

docs/index.html

Lines changed: 91 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,61 @@
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&nbsp;testing:&nbsp;</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:&nbsp;</strong>
89-
Reproduce real‑world utilisation scenarios so you can fine‑tune CPU quotas and scheduling policies.
90-
</li>
91-
<li>
92-
<strong>Benchmarking:&nbsp;</strong>
93-
Generate a consistent, repeatable workload that makes it easy to compare CPUs, machines, or configurations.
94-
</li>
95-
<li>
96-
<strong>Education&nbsp;&amp;&nbsp;training:&nbsp;</strong>
97-
Give students hands‑on experience with discrete PID control and demonstrate how load impacts performance.
98-
</li>
99-
<li>
100-
<strong>Thermal&nbsp;/&nbsp;power analysis:&nbsp;</strong>
101-
Investigate heat dissipation and energy consumption under a controlled, steady workload.
102-
</li>
79+
<li><strong>Performance&nbsp;testing:&nbsp;</strong>Stress‑test applications and full systems to uncover bottlenecks and verify robustness under load.</li>
80+
<li><strong>Resource‑allocation optimisation:&nbsp;</strong>Reproduce real‑world utilisation scenarios so you can fine‑tune CPU quotas and scheduling policies.</li>
81+
<li><strong>Benchmarking:&nbsp;</strong>Generate a consistent, repeatable workload that makes it easy to compare CPUs, machines, or configurations.</li>
82+
<li><strong>Education&nbsp;&amp;&nbsp;training:&nbsp;</strong>Give students hands‑on experience with discrete PID control and demonstrate how load impacts performance.</li>
83+
<li><strong>Thermal&nbsp;/&nbsp;power analysis:&nbsp;</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
133115
def generate_load(self, sleep_time):
134116
interval = time.time() + self.period - sleep_time
135-
while time.time() &lt; 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&nbsp;-c&nbsp;0&nbsp;-c&nbsp;3&nbsp;-l&nbsp;0.55&nbsp;-l&nbsp;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 &bull; © 2025 Gaetano Carlucci
191-
</footer>
192-
</body>
193-
</html>
121+
time.sleep(sleep_time)

0 commit comments

Comments
 (0)