From ba7424bb4d534b25c38696af1a5d4e2caa10d562 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 12 Nov 2025 15:47:54 +0100 Subject: [PATCH 1/2] fix: properly compute mW Time interval is in milliseconds, not seconds so need to multiply by 1000 --- .../power/sensors/linux/rapl/IntelRAPLSensor.java | 11 ++++++----- .../power/sensors/linux/rapl/IntelRAPLSensorTest.java | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java b/backend/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java index 801e4684..b1b0b53b 100644 --- a/backend/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java +++ b/backend/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java @@ -117,11 +117,12 @@ private double computePowerInMilliWatts(int componentIndex, long sensorValue, lo lastUpdateEpoch()); } - static double computePowerInMilliWatts(long newValue, long prevValue, long newMeasureTime, long prevMeasureTime) { - assert newValue > prevValue : "RAPL overflow occurred, need to deal with it!"; - assert newMeasureTime > prevMeasureTime : "Not enough time elapsed between measures or order of times problem"; - final var msBetweenMeasures = newMeasureTime - prevMeasureTime; - return (double) (newValue - prevValue) / msBetweenMeasures / 1000; + static double computePowerInMilliWatts(long newMicroJoules, long prevMicroJoules, long newMeasureTimeMS, + long prevMeasureTimeMS) { + assert newMicroJoules > prevMicroJoules : "RAPL overflow occurred, need to deal with it!"; + assert newMeasureTimeMS > prevMeasureTimeMS : "Not enough time elapsed between measures or order of times problem"; + final var msBetweenMeasures = newMeasureTimeMS - prevMeasureTimeMS; + return (double) (newMicroJoules - prevMicroJoules) / msBetweenMeasures; } @Override diff --git a/backend/src/test/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensorTest.java b/backend/src/test/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensorTest.java index 7045aa93..aa713797 100644 --- a/backend/src/test/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensorTest.java +++ b/backend/src/test/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensorTest.java @@ -76,7 +76,7 @@ public String contentAsString() { @Test void basicWattComputationShouldWork() { final var power = IntelRAPLSensor.computePowerInMilliWatts(200, 100, 2000, 1000); - assertEquals((double) 100 / 1000 / 1000, power); + assertEquals((double) 100 / 1000, power); } private static class TestIntelRAPLSensor extends IntelRAPLSensor { @@ -107,7 +107,7 @@ void wattComputationShouldWork() throws Exception { assertEquals(1, components.length); assertEquals(2, raplFile.callCount()); final var interval = raplFile.measureTimeFor(1) - raplFile.measureTimeFor(0); - final var expected = (double) (raplFile.valueAt(1) - raplFile.valueAt(0)) / interval / 1000; + final var expected = (double) (raplFile.valueAt(1) - raplFile.valueAt(0)) / interval; assertEquals(expected, components[0]); } From 8cba4f229812780122526898d1ce906faa8b9d72 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 12 Nov 2025 15:54:59 +0100 Subject: [PATCH 2/2] fix: duration calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason (race condition?), recording the calculation in the process exit callback sometimes fails… --- cli/src/main/java/net/laprun/sustainability/cli/Power.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/main/java/net/laprun/sustainability/cli/Power.java b/cli/src/main/java/net/laprun/sustainability/cli/Power.java index 36b5a4a5..e18c0a81 100644 --- a/cli/src/main/java/net/laprun/sustainability/cli/Power.java +++ b/cli/src/main/java/net/laprun/sustainability/cli/Power.java @@ -100,7 +100,7 @@ private Measure extractPowerConsumption(String applicationName) { private class ExternalProcessHandler extends BaseProcessHandler { private long startTime; - private long duration; + private long endTime; public ExternalProcessHandler(String cmd) { super("/bin/sh", "-c", stripped(cmd).orElseThrow()); @@ -119,13 +119,13 @@ public void onExit(int statusCode) { try { super.onExit(statusCode); } finally { - duration = System.currentTimeMillis() - this.startTime; + endTime = System.currentTimeMillis(); measurer.stop(); } } public long duration() { - return duration; + return endTime - startTime; } private static Optional stripped(String s) {