code wiki / _hdl_build / nx_energy_probe.nx
nx_energy_probe.nx
buildroot/runtime/_hdl_build/nx_energy_probe.nx
about
nx_energy_probe.nx -- REAL-hardware energy probe, HARDWARE-AGNOSTIC.
The gate-activity model (nx_gate_energy) gives a PORTABLE energy currency that
runs on any hardware. This probe is the other half: read the REAL energy the
NODE actually burns, using whatever sensor THIS silicon exposes, and degrade
gracefully when none exists -- never fabricating a joule we didn't measure.
Source priority (best real measurement first), detected at runtime:
RAPL -- x86 package energy counter via /sys (microjoules, accumulating). Real.
PSU -- battery fuel-gauge. The GARDEN-SENSOR / laptop-on-battery case. HONEST
RULE: a battery only attributes the CPU's energy while DISCHARGING --
on AC the wall adapter powers the CPU and the pack charges separately,
so a charging battery CANNOT measure the workload. And energy_now is
uWh-coarse (a short workload moves it by 0), so we integrate
instantaneous power_now (uW) x measured time (us) -> real microjoules.
I2C -- an INA219/INA260 current-sense chip on an I2C bus (/dev/i2c-*): the
canonical embedded power sensor. Detected; the INA219 register read
streams in as a later SEED piece (honest: not faked here).
CYCLE -- rdtsc/rdcycle: ALWAYS available, every target (the compiler lowers
__rdtsc to rdcycle on RV64/ARM). NOT a sad fallback: the cycle COUNT is
itself CHARGE-INDEPENDENT, and nx_energy_model turns it into real joules
via a calibrated fJ/cycle -> energy is measurable in ANY power state.
IMPORTANT (operator: "only measuring when not charging is not S-class"): the
S-class path does NOT depend on the battery. RAPL and an INA219 rail sensor are
state-independent; nx_energy_model + nx_perf_counters give real joules from
charge-independent activity counters (cycles/instructions) on ANY node in ANY
power state. The battery-discharge path is only a calibration source, demoted
below the state-independent ones. Cardinal #14: a missing sensor is never a
failure -- fall through to the universal charge-independent estimator.
CITATIONS (real): RAPL -- Intel SDM Vol.3B; Khan et al., ACM TOMPECS 2018. Battery
-- Linux power_supply class (Documentation/power/power_supply_class.rst, GPL).
Rail sensor -- TI INA219 datasheet (SBOS448). Activity->energy -- Horowitz, ISSCC
2014; Bircher & John, ISPASS 2007.
dependencies 1 imports · 1 importers
imports: nx_syscalls.nx
imported by: nx_energy_probe_test.nx
structs
| none |
consts
| 39 | const ENERGY_SRC_NONE: i64 = 0 |
| 40 | const ENERGY_SRC_RAPL: i64 = 1 |
| 41 | const ENERGY_SRC_PSU: i64 = 2 |
| 42 | const ENERGY_SRC_I2C: i64 = 3 |
| 43 | const ENERGY_SRC_CYCLE: i64 = 4 |
functions
| 45 | func ep_file_readable(path: *u8) -> i64 |
| 53 | func ep_read_decimal_file(path: *u8) -> i64 |
| 74 | func ep_read_first_char(path: *u8) -> i64 |
| 85 | func ep_psu_present() -> i64 |
| 91 | func ep_psu_discharging() -> i64 |
| 97 | func ep_psu_power_uw() -> i64 |
| 104 | func ep_detect() -> i64 |
| 113 | func ep_read(src: i64) -> i64 |
| 120 | func ep_src_name(src: i64) -> *u8 called by 1: main |
| 129 | func ep_is_joule_source(src: i64) -> i64 called by 1: main |
| 135 | func ep_is_power_source(src: i64) -> i64 called by 1: main |