Skip to content

Commit fcf759a

Browse files
Update index.html
1 parent 234cbfc commit fcf759a

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

docs/index.html

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,179 @@
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>
17

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>
63+
64+
<!-- ===== Hero ===== -->
65+
<header>
66+
<h1>CPU Load Generator</h1>
67+
<p>
68+
Generate a steady CPU load with a simple PID‑based Python script.<br />
69+
<a href="https://github.com/GaetanoCarlucci/CPULoadGenerator"
70+
target="_blank" rel="noopener">View the project on GitHub ↗︎</a>
71+
</p>
72+
</header>
73+
74+
<main>
75+
76+
<!-- ===== Motivation ===== -->
77+
<section id="motivation">
78+
<h2>Motivation</h2>
79+
<p>
80+
This tool helps system administrators, developers and researchers
81+
create a <strong>fixed CPU load for a finite period</strong> using a PID regulator. :contentReference[oaicite:0]{index=0}
82+
</p>
83+
<ul>
84+
<li><strong>Performance testing:</strong> stress‑test applications to uncover bottlenecks.</li>
85+
<li><strong>Resource‑allocation optimisation:</strong> simulate load scenarios and tune CPU quotas.</li>
86+
<li><strong>Benchmarking:</strong> create repeatable loads to compare hardware or configurations.</li>
87+
<li><strong>Education &amp; training:</strong> demonstrate PID control and CPU‑load behaviour in practice.</li>
88+
<li><strong>Thermal / power analysis:</strong> study heat dissipation and power draw under controlled load.</li>
89+
</ul>
90+
</section>
91+
92+
<!-- ===== PID Regulator ===== -->
93+
<section id="pid">
94+
<h2>PID regulator for controlling CPU load</h2>
95+
<img src="https://gaetanocarlucci.altervista.org/wp-content/uploads/2024/07/pid-1.png"
96+
alt="PID control diagram" loading="lazy">
97+
<p>
98+
The architecture uses two threads: a <em>Monitor Thread</em> that measures CPU
99+
utilisation and a <em>Controller Thread</em> that applies PI control to adjust
100+
the sleep time of a tight loop so the measured load matches the
101+
target. :contentReference[oaicite:1]{index=1}
102+
</p>
103+
104+
<h3>Monitor Thread</h3>
105+
<p>
106+
Samples CPU usage at a fixed interval via
107+
<code>psutil.cpu_percent(interval)</code>, filters the measurements with a
108+
first‑order filter and logs the results. :contentReference[oaicite:2]{index=2}
109+
</p>
110+
111+
<h3>Controller Thread</h3>
112+
<p>
113+
Compares the target load (<em>set‑point</em>) and actual load, then computes the
114+
control signal using proportional (<code>K<sub>p</sub></code>) and integral
115+
(<code>K<sub>i</sub></code>) actions. The derivative term is not used. :contentReference[oaicite:3]{index=3}
116+
</p>
117+
118+
<pre><code># actuator snippet
119+
def generate_load(self, sleep_time):
120+
interval = time.time() + self.period - sleep_time
121+
while time.time() &lt; interval:
122+
pr = 213123 # busy‑work
123+
_ = pr * pr
124+
pr = pr + 1
125+
time.sleep(sleep_time)</code></pre>
126+
127+
<pre><code># main PI control loop
128+
def run(self):
129+
def cpu_model(cpu_period):
130+
return self.period - cpu_period # maps period to sleep time
131+
132+
self.shutdown_flag.clear()
133+
while not self.shutdown_flag.is_set():
134+
time.sleep(self.sampling_interval)
135+
136+
with self.target_lock, self.cpu_lock:
137+
CT = self.CT # target load
138+
cpu = self.cpu # measured load
139+
140+
self.err = CT - cpu * 0.01
141+
ts = time.time()
142+
samp_int = ts - self.last_ts
143+
self.int_err += self.err * samp_int
144+
self.last_ts = ts
145+
self.cpuPeriod = (self.kp * self.err +
146+
self.ki * self.int_err)
147+
148+
# anti‑windup
149+
self.cpuPeriod = max(0, min(self.cpuPeriod, self.period))
150+
self.set_sleep_time(cpu_model(self.cpuPeriod))</code></pre>
151+
152+
<h3>PI tuning insights</h3>
153+
<p>
154+
Raising <code>K<sub>p</sub></code> speeds up the response but risks overshoot; adding an
155+
integral term removes steady‑state error at the cost of sluggishness
156+
and potential oscillations, so anti‑windup is essential. :contentReference[oaicite:4]{index=4}
157+
</p>
158+
</section>
159+
160+
<!-- ===== Results ===== -->
161+
<section id="results">
162+
<h2>Results</h2>
163+
<p>
164+
Quick test in a GitHub Codespace or local shell:
165+
<code>./CPULoadGenerator.py&nbsp;-c&nbsp;0&nbsp;-c&nbsp;3&nbsp;-l&nbsp;0.55&nbsp;-l&nbsp;0.12</code>
166+
</p>
167+
168+
<p>Example 50 % target load on core 0 for 20 s:</p>
169+
<img src="https://gaetanocarlucci.altervista.org/wp-content/uploads/2024/07/50-Target-Load.png"
170+
alt="CPU‑load plot" loading="lazy">
171+
</section>
172+
173+
</main>
174+
175+
<footer>
176+
MIT License &bull; © 2025 Gaetano Carlucci
177+
</footer>
178+
</body>
179+
</html>

0 commit comments

Comments
 (0)