Skip to content

Commit 9c9babe

Browse files
committed
docs: complete README rewrite (FastAnimation style) — Why FastHardware, Key Features, Real-Life Examples, full API table, ACPI limitation note; fix: WMI ROOT\WMI dual connection for real CPU temp, remove 45.0 hardcode
1 parent a67388f commit 9c9babe

3 files changed

Lines changed: 194 additions & 88 deletions

File tree

README.md

Lines changed: 161 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,164 @@
1-
# FastHardware 0.1.1 — Native Hardware Telemetry API for Java
1+
# FastHardware 0.1.1 [ALPHA-2026-09-02] — Native Hardware Telemetry API for Java
22

33
[![Status](https://img.shields.io/badge/status-0.1.1-brightgreen.svg)](https://github.com/andrestubbe/FastHardware/releases/tag/0.1.1)
44
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
55
[![Java](https://img.shields.io/badge/Java-17+-blue.svg)](https://www.java.com)
66
[![Platform](https://img.shields.io/badge/Platform-Windows%2010+-lightgrey.svg)]()
77
[![JitPack](https://img.shields.io/badge/JitPack-ready-green.svg)](https://jitpack.io/#andrestubbe/FastHardware)
88

9-
**⚡ Zero-overhead native hardware telemetry for Java. Monitor CPU usage, CPU temperature, RAM, and GPU temperature directly via Win32 PDH and WMI — no JMX, no process spawning, no bloat.**
9+
---
10+
11+
**⚡ Zero-overhead native hardware telemetry for Java.**
1012

11-
**FastHardware** bypasses the JVM's heavy `OperatingSystemMXBean` and shell-based `wmic` calls entirely. By binding directly to Win32 PDH counters and WMI COM objects via JNI, it delivers accurate, low-latency hardware telemetry at native speed.
13+
**FastHardware** gives your Java application direct access to real-time system health — CPU usage, CPU temperature, physical RAM, and GPU temperature — without shelling out to `wmic`, without polling `OperatingSystemMXBean`, and without spawning background processes. By binding directly to Win32 PDH counters and WMI COM objects via JNI, it delivers accurate, low-latency hardware telemetry at native speed.
14+
15+
[**Watch the Demo (YouTube)**](https://www.youtube.com/watch?v=BZsqQl7WqWk)
1216

1317
[![FastHardware Showcase](docs/screenshot.png)](https://www.youtube.com/watch?v=BZsqQl7WqWk)
1418

1519
---
1620

21+
## Quick Start
22+
23+
```java
24+
import fasthardware.FastHardware;
25+
import fasthardware.HardwareSnapshot;
26+
27+
public class Example {
28+
public static void main(String[] args) throws InterruptedException {
29+
// Initialize once — opens PDH query + WMI COM connection
30+
FastHardware hw = FastHardware.create();
31+
32+
// PDH CPU counters need one collection interval (~1s) before returning real data
33+
Thread.sleep(1100);
34+
35+
// Atomic snapshot of all telemetry in a single native call
36+
HardwareSnapshot snap = hw.getSnapshot();
37+
38+
System.out.printf("CPU Usage: %.1f%%%n", snap.cpuUsagePercent());
39+
System.out.printf("CPU Temp: %.1f°C%n", snap.cpuTemperatureCelsius());
40+
System.out.printf("RAM Free: %d MB%n", snap.freeRamBytes() / 1024 / 1024);
41+
System.out.printf("RAM Total: %d MB%n", snap.totalRamBytes() / 1024 / 1024);
42+
System.out.printf("GPU Temp: %.1f°C%n", snap.gpuTemperatureCelsius());
43+
44+
// Or query individual metrics
45+
double[] perCore = hw.getPerCoreCpuUsage();
46+
for (int i = 0; i < perCore.length; i++) {
47+
System.out.printf(" Core %d: %.1f%%%n", i, perCore[i]);
48+
}
49+
}
50+
}
51+
```
52+
53+
---
54+
1755
## Table of Contents
18-
- [Features](#features)
19-
- [Quick Start](#quick-start)
20-
- [API Quick Reference](#api-quick-reference)
56+
57+
- [Why FastHardware?](#why-fasthardware)
58+
- [Key Features](#key-features)
59+
- [Real-Life Examples](#real-life-examples)
2160
- [Performance Benchmarks](#performance-benchmarks)
61+
- [API Quick Reference](#api-quick-reference)
2262
- [Examples & Demos](#examples--demos)
2363
- [Installation](#installation)
2464
- [Documentation](#documentation)
2565
- [Platform Support](#platform-support)
26-
- [Related Projects](#related-projects)
2766
- [License](#license)
67+
- [Related Projects](#related-projects)
2868

2969
---
3070

31-
## Features
71+
## Why FastHardware?
72+
73+
Standard Java approaches to hardware monitoring have fundamental limitations when used in production:
74+
75+
- **`OperatingSystemMXBean`**: Only provides a 1-minute rolling load average (`getSystemLoadAverage()`) — not real-time CPU usage. Has no temperature, no per-core data, and no physical RAM (only JVM heap).
76+
- **`Runtime.freeMemory()`**: Reports JVM heap free memory only — completely unrelated to OS-level physical RAM.
77+
- **`wmic` / process spawning**: Executes a child process per call. Startup overhead is ~100–300 ms per query, utterly unsuitable for polling loops.
78+
- **No thermal sensor API**: Java has zero built-in access to CPU or GPU temperature. There is no standard API — full stop.
3279

33-
- **📊 Real-Time Telemetry** — CPU usage %, per-core CPU usage, CPU temperature, physical RAM, GPU temperature.
34-
- **⚡ Native Win32 Speed** — PDH counters (`\\Processor(_Total)\\% Processor Time`) registered once, polled in microseconds. RAM via `GlobalMemoryStatusEx` (direct kernel table read). Temperature via WMI `MSAcpi_ThermalZoneTemperature` in `ROOT\WMI`.
35-
- **🧊 Zero Overhead** — All JNI calls use primitives (`jlong`, `jdouble`, `jdoubleArray`). No heap allocation per query.
36-
- **📦 Atomic Snapshot**`getSnapshot()` returns a frozen `HardwareSnapshot` record with all fields captured in a single native round-trip.
37-
- **🔌 FastCore Auto-Load**`fasthardware.dll` is embedded in the JAR. `FastCore` extracts and loads it at runtime — no manual DLL management.
80+
**FastHardware** solves all of these by going directly to the OS:
81+
82+
- **True CPU Usage**: PDH counter `\\Processor(_Total)\\% Processor Time` — registered once at startup, polled in microseconds for every subsequent call. Real-time, not delayed.
83+
- **Physical RAM**: Win32 `GlobalMemoryStatusEx` — a direct kernel memory table read in nanoseconds, returns actual OS-level free and total physical RAM.
84+
- **Temperature**: WMI `MSAcpi_ThermalZoneTemperature` in the `ROOT\WMI` namespace — native ACPI thermal zone readings via COM without any process spawn.
85+
- **Per-Core CPU**: One PDH counter per logical core, all polled in a single JNI call, returned as a `double[]`.
3886

3987
---
4088

41-
## Quick Start
89+
## Key Features
90+
91+
- **📊 Real-Time Telemetry** — CPU%, per-core CPU%, CPU temperature, physical free RAM, total RAM, GPU temperature.
92+
- **⚡ Native Win32 Speed** — PDH counters registered once, polled in microseconds. RAM via `GlobalMemoryStatusEx`. Temperatures via WMI ACPI.
93+
- **🧊 Zero Heap Allocation** — All JNI calls use primitives (`jlong`, `jdouble`, `jdoubleArray`). No objects allocated per query. GC-invisible hot path.
94+
- **📦 Atomic Snapshot**`getSnapshot()` captures all fields in a single native round-trip and returns a frozen `HardwareSnapshot` record.
95+
- **🔌 Auto-Loading Native**`fasthardware.dll` is embedded inside the JAR. `FastCore` extracts and loads it automatically at runtime — no manual DLL path management.
96+
- **🖥️ Ecosystem Ready** — Integrates cleanly into the FastJava ecosystem. Feed telemetry into `FastAgent`, drive adaptive quality in `FastAnimation`, or gate resource-intensive `FastGPU` kernels.
97+
98+
---
99+
100+
## Real-Life Examples
101+
102+
**System Health Dashboard** — poll every 500 ms and print live data:
103+
```java
104+
FastHardware hw = FastHardware.create();
105+
hw.getSnapshot(); Thread.sleep(1100); // warm up PDH
106+
107+
while (true) {
108+
HardwareSnapshot s = hw.getSnapshot();
109+
System.out.printf("\rCPU: %4.1f%% Temp: %2.0f°C RAM: %4.0f MB free",
110+
s.cpuUsagePercent(),
111+
s.cpuTemperatureCelsius(),
112+
s.freeRamBytes() / 1024.0 / 1024.0);
113+
Thread.sleep(500);
114+
}
115+
```
42116

117+
**Adaptive Quality Gate** — throttle workload when system is under pressure:
43118
```java
44-
// 1. Create a hardware monitor instance (initializes PDH + WMI once)
45119
FastHardware hw = FastHardware.create();
46120

47-
// First PDH sample needs ~1s interval to compute CPU rate
48-
Thread.sleep(1100);
121+
public void onTick() {
122+
double cpu = hw.getGlobalCpuUsage();
123+
long freeRam = hw.getFreeMemoryBytes();
49124

50-
// 2. Get an atomic snapshot of all telemetry
51-
HardwareSnapshot snap = hw.getSnapshot();
125+
if (cpu > 85.0 || freeRam < 512 * 1024 * 1024L) {
126+
renderEngine.setQuality(Quality.LOW); // back off
127+
} else {
128+
renderEngine.setQuality(Quality.HIGH); // full power
129+
}
130+
}
131+
```
52132

53-
System.out.printf("CPU: %.1f%%%n", snap.cpuUsagePercent());
54-
System.out.printf("CPU Temp: %.1f°C%n", snap.cpuTemperatureCelsius());
55-
System.out.printf("RAM: %d MB free / %d MB total%n",
56-
snap.freeRamBytes() / 1024 / 1024,
57-
snap.totalRamBytes() / 1024 / 1024);
58-
System.out.printf("GPU Temp: %.1f°C%n", snap.gpuTemperatureCelsius());
133+
**Per-Core Imbalance Detection** — find overloaded cores:
134+
```java
135+
double[] cores = hw.getPerCoreCpuUsage();
136+
for (int i = 0; i < cores.length; i++) {
137+
if (cores[i] > 90.0) {
138+
System.out.printf("⚠ Core %d overloaded: %.1f%%%n", i, cores[i]);
139+
}
140+
}
59141
```
60142

61-
> [!IMPORTANT]
62-
> PDH CPU counters require **two collection intervals** to compute a rate. Call `hw.getSnapshot()` once, wait ~1 second, then read real values. FastHardware handles this automatically after the first poll.
143+
---
144+
145+
## Performance Benchmarks
146+
147+
FastHardware is profiled using **JMH** against standard Java equivalents. Run `run-benchmark.bat` for live numbers.
148+
149+
| Metric | Java JMX / Runtime | FastHardware Native | Notes |
150+
|--------|--------------------|---------------------|-------|
151+
| Full telemetry snapshot | 3× separate MXBean calls | **1× atomic JNI call** | PDH + WMI + RAM in one trip |
152+
| CPU usage | `getSystemLoadAverage()` (1-min rolling) | **PDH instantaneous** | Real-time vs. delayed average |
153+
| Per-core CPU | ❌ Not available | **`double[]` per logical core** | FastHardware exclusive |
154+
| Free RAM | `Runtime.freeMemory()` (JVM heap only) | **`GlobalMemoryStatusEx` (physical)** | OS-level, not JVM-scoped |
155+
| CPU temperature | ❌ Not available | **WMI ACPI `ROOT\WMI`** | FastHardware exclusive |
156+
| GPU temperature | ❌ Not available | **WMI (discrete GPUs)** | FastHardware exclusive |
157+
158+
> [!NOTE]
159+
> CPU temperature accuracy depends on BIOS ACPI implementation. Intel integrated GPU platforms may report static ACPI thermal zone values — this is a firmware limitation, not a FastHardware bug. Discrete NVIDIA/AMD GPUs and desktop motherboards typically provide continuously updating values.
160+
161+
*Measured on Windows 11, Intel Core i5-1135G7 (Surface Pro 8), JDK 21.0.12.*
63162

64163
---
65164

@@ -69,14 +168,14 @@ System.out.printf("GPU Temp: %.1f°C%n", snap.gpuTemperatureCelsius());
69168

70169
| Method | Returns | Description |
71170
|--------|---------|-------------|
72-
| `FastHardware.create()` | `FastHardware` | Initializes the native library and returns a monitor instance. |
73-
| `getSnapshot()` | `HardwareSnapshot` | Atomic read of all telemetry fields in one native call. |
74-
| `getGlobalCpuUsage()` | `double` | CPU usage 0.0–100.0 via PDH `\\Processor(_Total)\\% Processor Time`. |
75-
| `getPerCoreCpuUsage()` | `double[]` | Per-logical-core CPU usage array via PDH. |
171+
| `FastHardware.create()` | `FastHardware` | Initializes native PDH + WMI and returns a monitor instance. |
172+
| `getSnapshot()` | `HardwareSnapshot` | Atomic read of all telemetry in one native call. |
173+
| `getGlobalCpuUsage()` | `double` | CPU usage 0.0–100.0 via PDH `\\Processor(_Total)`. |
174+
| `getPerCoreCpuUsage()` | `double[]` | Per-logical-core CPU usage via PDH. |
76175
| `getTotalMemoryBytes()` | `long` | Total physical RAM via `GlobalMemoryStatusEx`. |
77176
| `getFreeMemoryBytes()` | `long` | Free physical RAM via `GlobalMemoryStatusEx`. |
78-
| `getCpuTemperatureCelsius()` | `double` | CPU package temperature via WMI `MSAcpi_ThermalZoneTemperature` in `ROOT\WMI`. |
79-
| `getGpuTemperatureCelsius()` | `double` | GPU temperature via WMI (discrete GPUs; `0.0` on Intel integrated). |
177+
| `getCpuTemperatureCelsius()` | `double` | CPU temperature via WMI ACPI `ROOT\WMI`. |
178+
| `getGpuTemperatureCelsius()` | `double` | GPU temperature via WMI (0.0 if not available). |
80179

81180
### `HardwareSnapshot` (Record)
82181

@@ -89,42 +188,26 @@ record HardwareSnapshot(
89188
double cpuTemperatureCelsius,
90189
double gpuTemperatureCelsius
91190
) {
92-
long freeRamBytes(); // helper: totalRamBytes - usedRamBytes
191+
long freeRamBytes(); // totalRamBytes - usedRamBytes
93192
}
94193
```
95194

96195
---
97196

98-
## Performance Benchmarks
99-
100-
FastHardware native Win32 JNI vs standard Java `OperatingSystemMXBean` / `Runtime`:
101-
102-
| Metric | Java JMX / Runtime | FastHardware Native | Advantage |
103-
|--------|--------------------|---------------------|-----------|
104-
| Full telemetry snapshot | 3× separate MXBean calls | **1× atomic JNI call** | **3× fewer round-trips** |
105-
| CPU usage query | `getSystemLoadAverage()` (1-min rolling) | **PDH instantaneous** | **Real-time vs delayed** |
106-
| Per-core CPU usage | ❌ No API | **`double[]` per logical core** | **FastHardware exclusive** |
107-
| Free RAM (OS-level) | `Runtime.freeMemory()` (JVM heap only) | **`GlobalMemoryStatusEx` (physical)** | **System-wide accuracy** |
108-
| CPU temperature | ❌ No API | **WMI `ROOT\WMI` ACPI sensor** | **FastHardware exclusive** |
109-
| GPU temperature | ❌ No API | **WMI discrete GPU sensor** | **FastHardware exclusive** |
110-
111-
*Run `run-benchmark.bat` for live JMH throughput numbers on your machine.*
112-
113-
---
114-
115197
## Examples & Demos
116198

117-
| Case | File | Launcher | Description |
118-
|------|------|----------|-------------|
119-
| **Live Terminal Dashboard** | [Demo.java](examples/Demo/src/main/java/fasthardware/Demo.java) | `run-demo.bat` | ANSI terminal monitor — CPU%, CPU°C, RAM, GPU°C as live bars + scrolling sparklines. Pure FastHardware, no extra deps. |
120-
| **JMH Benchmark Suite** | [Benchmark.java](examples/Benchmark/src/main/java/fasthardware/benchmark/Benchmark.java) | `run-benchmark.bat` | 7-group JMH throughput suite comparing FastHardware native vs Java JMX/Runtime. |
199+
| Case | Java Example | Launcher | Description |
200+
|------|--------------|----------|-------------|
201+
| **Live Terminal Dashboard** | [Demo.java](examples/Demo/src/main/java/fasthardware/Demo.java) | `run-demo.bat` | ANSI terminal monitor — CPU%, CPU°C, RAM, GPU°C as neon bars + scrolling sparklines. Pure FastHardware, no extra deps. |
202+
| **JMH Benchmark Suite** | [Benchmark.java](examples/Benchmark/src/main/java/fasthardware/benchmark/Benchmark.java) | `run-benchmark.bat` | 7-group JMH throughput suite FastHardware native vs Java JMX/Runtime across all telemetry dimensions. |
121203

122204
---
123205

124206
## Installation
125207

126208
### Option 1: Maven (Recommended)
127-
Add the JitPack repository and the dependencies to your `pom.xml`:
209+
210+
Add the JitPack repository and the dependency to your `pom.xml`:
128211

129212
```xml
130213
<repositories>
@@ -141,8 +224,7 @@ Add the JitPack repository and the dependencies to your `pom.xml`:
141224
<artifactId>FastHardware</artifactId>
142225
<version>0.1.1</version>
143226
</dependency>
144-
145-
<!-- FastCore (Required Native Loader) -->
227+
<!-- FastCore — Required Native JNI Loader -->
146228
<dependency>
147229
<groupId>com.github.andrestubbe</groupId>
148230
<artifactId>FastCore</artifactId>
@@ -152,6 +234,7 @@ Add the JitPack repository and the dependencies to your `pom.xml`:
152234
```
153235

154236
### Option 2: Gradle (via JitPack)
237+
155238
```groovy
156239
repositories {
157240
maven { url 'https://jitpack.io' }
@@ -164,24 +247,23 @@ dependencies {
164247
```
165248

166249
### Option 3: Direct Download (No Build Tool)
250+
167251
1. 📦 **[FastHardware-0.1.1.jar](https://github.com/andrestubbe/FastHardware/releases/download/0.1.1/FastHardware-0.1.1.jar)** — The Core Library
168-
2. ⚙️ **[FastCore-0.1.0.jar](https://github.com/andrestubbe/FastCore/releases/download/0.1.0/fastcore-0.1.0.jar)**The Mandatory Native Loader
252+
2. ⚙️ **[fastcore-0.1.0.jar](https://github.com/andrestubbe/FastCore/releases/download/0.1.0/fastcore-0.1.0.jar)**Required Native JNI Loader
169253

170254
> [!IMPORTANT]
171-
> Both JARs must be on your classpath. FastCore extracts `fasthardware.dll` to `%USERPROFILE%\.fastcore\native\` at runtime.
255+
> Both JARs must be on your classpath. `FastCore` extracts `fasthardware.dll` to `%USERPROFILE%\.fastcore\native\fasthardware\` at runtime automatically.
172256
173257
---
174258

175259
## Documentation
176260

177-
| File | Description |
178-
|------|-------------|
179-
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Win32 PDH, WMI COM, and JNI boundary details. |
180-
| [REFERENCE.md](docs/REFERENCE.md) | Full API specification and JNI contracts. |
181-
| [COMPILE.md](docs/COMPILE.md) | Build guide for the native DLL from source. |
182-
| [PHILOSOPHY.md](docs/PHILOSOPHY.md) | Why native-first telemetry matters in Java. |
183-
| [CHANGELOG.md](docs/CHANGELOG.md) | Version history. |
184-
| [ROADMAP.md](docs/ROADMAP.md) | Future development milestones. |
261+
* **[ARCHITECTURE.md](docs/ARCHITECTURE.md)**: Win32 PDH, WMI COM bridge, and JNI boundary architecture.
262+
* **[REFERENCE.md](docs/REFERENCE.md)**: Full API specification and JNI contracts.
263+
* **[COMPILE.md](docs/COMPILE.md)**: Build guide for compiling the native DLL from C++ source.
264+
* **[PHILOSOPHY.md](docs/PHILOSOPHY.md)**: Why native-first telemetry matters for Java performance monitoring.
265+
* **[CHANGELOG.md](docs/CHANGELOG.md)**: Version history and release notes.
266+
* **[ROADMAP.md](docs/ROADMAP.md)**: Planned milestones (NVAPI, ADL, async background poller).
185267

186268
---
187269

@@ -190,8 +272,14 @@ dependencies {
190272
| Platform | Status |
191273
|----------|--------|
192274
| Windows 10 / 11 (x64) | ✅ Fully Supported |
193-
| Linux | 🔜 Planned |
194-
| macOS | 🔜 Planned |
275+
| Linux | 🚧 Planned |
276+
| macOS | 🚧 Planned |
277+
278+
---
279+
280+
## License
281+
282+
MIT License — See [LICENSE](LICENSE) for details.
195283

196284
---
197285

@@ -202,7 +290,9 @@ dependencies {
202290
- [FastGPU](https://github.com/andrestubbe/FastGPU) — Vulkan compute kernel dispatch for Java
203291
- [FastDisplay](https://github.com/andrestubbe/FastDisplay) — Native display refresh rate and resolution detection
204292
- [FastExecution](https://github.com/andrestubbe/FastExecution) — Sub-millisecond precision named loop and delay scheduler
293+
- [FastAnimation](https://github.com/andrestubbe/FastAnimation) — Ultra-fast native timeline animation engine
294+
- [FastTween](https://github.com/andrestubbe/FastTween) — Zero-overhead pooled tweening engine
205295

206296
---
207297

208-
**Part of the FastJava Ecosystem***Making the JVM faster. Small package. Maximum speed. Zero bloat.* 🚀
298+
**Part of the FastJava Ecosystem***Making the JVM faster. Small package. Maximum speed. Zero bloat. 🚀🔋*

0 commit comments

Comments
 (0)