Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions measure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.hdrhistogram</groupId>
<artifactId>HdrHistogram</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.laprun.sustainability.power.measure;

import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

class DescriptiveStatisticsMeasureStore implements MeasureStore {
private final int totalIndex;
private final DescriptiveStatistics[] measures;

public DescriptiveStatisticsMeasureStore(int componentsNumber, int initialWindow) {
this.measures = new DescriptiveStatistics[componentsNumber + 1];
totalIndex = componentsNumber;
for (int i = 0; i < measures.length; i++) {
measures[i] = new DescriptiveStatistics(initialWindow);
}
}

@Override
public void recordComponentValue(int component, double value) {
getMeasure(component).addValue(value);
}

private DescriptiveStatistics getMeasure(int component) {
return measures[component];
}

private DescriptiveStatistics getTotalMeasure() {
return getMeasure(totalIndex);
}

@Override
public void recordTotal(double value) {
getTotalMeasure().addValue(value);
}

@Override
public double getMeasuredTotal() {
return getTotalMeasure().getSum();
}

@Override
public double getComponentStandardDeviation(int component) {
return getMeasure(component).getStandardDeviation();
}

@Override
public double getTotalStandardDeviation() {
return getTotalMeasure().getStandardDeviation();
}

@Override
public double[] getComponentRawValues(int component) {
return getMeasure(component).getValues();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package net.laprun.sustainability.power.measure;

import org.HdrHistogram.HistogramIterationValue;
import org.HdrHistogram.IntCountsHistogram;

public class HdrHistogramMeasureStore implements MeasureStore {
private static final int HIGHEST_TRACKABLE_VALUE = 1_000_000;
private static final int NUMBER_OF_SIGNIFICANT_VALUE_DIGITS = 4;
private static final int CONVERSION_FACTOR = 1000;
private final IntCountsHistogram[] measures;
private final int totalIndex;
private double accumulatedTotal;

public HdrHistogramMeasureStore(int componentsNumber, int initialWindow) {
totalIndex = componentsNumber;
measures = new IntCountsHistogram[componentsNumber + 1];
for (int i = 0; i < measures.length; i++) {
measures[i] = new IntCountsHistogram(HIGHEST_TRACKABLE_VALUE,
NUMBER_OF_SIGNIFICANT_VALUE_DIGITS);
}
}

private IntCountsHistogram getMeasure(int component) {
return measures[component];
}

private IntCountsHistogram getTotalMeasure() {
return getMeasure(totalIndex);
}

@Override
public void recordComponentValue(int component, double value) {
getMeasure(component).recordValue((long) (CONVERSION_FACTOR * value));
}

@Override
public void recordTotal(double value) {
getTotalMeasure().recordValue((long) (CONVERSION_FACTOR * value));
accumulatedTotal += value;
}

@Override
public double getMeasuredTotal() {
return accumulatedTotal;
}

@Override
public double getComponentStandardDeviation(int component) {
return getMeasure(component).getStdDeviation() / CONVERSION_FACTOR;
}

@Override
public double getTotalStandardDeviation() {
// not unbiased so tests will fail
return getTotalMeasure().getStdDeviation();
}

@Override
public double[] getComponentRawValues(int component) {
final var measure = getMeasure(component);
final var totalCount = measure.getTotalCount();
final var result = new double[(int) totalCount];
int index = 0;
for (HistogramIterationValue value : measure.recordedValues()) {
result[index++] = (double) value.getValueIteratedTo() / CONVERSION_FACTOR;
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.laprun.sustainability.power.measure;

interface MeasureStore {
void recordComponentValue(int component, double value);

void recordTotal(double value);

double getMeasuredTotal();

double getComponentStandardDeviation(int component);

double getTotalStandardDeviation();

double[] getComponentRawValues(int component);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

import net.laprun.sustainability.power.SensorMetadata;

public class OngoingPowerMeasure implements PowerMeasure {
private final SensorMetadata sensorMetadata;
private final DescriptiveStatistics[] measures;
private final DescriptiveStatistics total;
private final MeasureStore measures;
private final long startedAt;
private final double[] averages;
private final Set<Integer> nonZeroComponents;
private final int[] totalComponents;
private double minTotal = Double.MAX_VALUE;
private double maxTotal;
private int samples;
Expand All @@ -26,13 +24,10 @@ public OngoingPowerMeasure(SensorMetadata sensorMetadata, Duration duration, Dur
averages = new double[numComponents];

final var initialWindow = (int) (duration.toMillis() / frequency.toMillis());
total = new DescriptiveStatistics(initialWindow);
this.measures = new DescriptiveStatistics[numComponents];
for (int i = 0; i < measures.length; i++) {
measures[i] = new DescriptiveStatistics(initialWindow);
}
measures = new DescriptiveStatisticsMeasureStore(numComponents, initialWindow);

nonZeroComponents = new HashSet<>(numComponents);
totalComponents = sensorMetadata.totalComponents();
}

@Override
Expand All @@ -54,14 +49,14 @@ public void recordMeasure(double[] components) {
if (componentValue != 0) {
nonZeroComponents.add(component);
}
measures[component].addValue(componentValue);
measures.recordComponentValue(component, componentValue);
averages[component] = averages[component] == 0 ? componentValue
: (previousSize * averages[component] + componentValue) / samples;
}

// record min / max totals
final var recordedTotal = PowerMeasure.sumOfSelectedComponents(components, metadata().totalComponents());
total.addValue(recordedTotal);
final var recordedTotal = PowerMeasure.sumOfSelectedComponents(components, totalComponents);
measures.recordTotal(recordedTotal);
if (recordedTotal < minTotal) {
minTotal = recordedTotal;
}
Expand All @@ -72,7 +67,7 @@ public void recordMeasure(double[] components) {

@Override
public double total() {
return total.getSum();
return measures.getMeasuredTotal();
}

public Duration duration() {
Expand All @@ -99,13 +94,13 @@ public StdDev standardDeviations() {
final var stdDevs = new double[cardinality];
nonZeroComponents.stream()
.parallel()
.forEach(component -> stdDevs[component] = measures[component].getStandardDeviation());
.forEach(component -> stdDevs[component] = measures.getComponentStandardDeviation(component));

return new StdDev(total.getStandardDeviation(), stdDevs);
return new StdDev(measures.getTotalStandardDeviation(), stdDevs);
}

@Override
public double[] getMeasuresFor(int component) {
return measures[component].getValues();
return measures.getComponentRawValues(component);
}
}