-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
io: calculate IO bandwidth per IO block
- Loading branch information
Showing
4 changed files
with
131 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package org.dcache.nearline.cta.xrootd; | ||
|
||
// rip off RequestExecutionTimeGaugeImpl#Statistics | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* Encapsulates an online algorithm for maintaining various statistics about samples. | ||
* <p> | ||
* See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance for an explanation. | ||
*/ | ||
public class IoStats { | ||
|
||
private double mean; | ||
private double m2; | ||
private double min = Double.NaN; | ||
private double max = Double.NaN; | ||
private long n; | ||
|
||
public synchronized void update(double x) { | ||
this.min = this.n == 0L ? x : Math.min(x, this.min); | ||
this.max = this.n == 0L ? x : Math.max(x, this.max); | ||
++this.n; | ||
double nextMean = this.mean + (x - this.mean) / (double) this.n; | ||
double nextM2 = this.m2 + (x - this.mean) * (x - nextMean); | ||
this.mean = nextMean; | ||
this.m2 = nextM2; | ||
} | ||
|
||
public synchronized double getMean() { | ||
return this.n > 0L ? this.mean : Double.NaN; | ||
} | ||
|
||
public synchronized double getSampleVariance() { | ||
return this.n > 1L ? this.m2 / (double) (this.n - 1L) : Double.NaN; | ||
} | ||
|
||
public synchronized double getPopulationVariance() { | ||
return this.n > 0L ? this.m2 / (double) this.n : Double.NaN; | ||
} | ||
|
||
public synchronized double getSampleStandardDeviation() { | ||
return Math.sqrt(this.getSampleVariance()); | ||
} | ||
|
||
public synchronized double getPopulationStandardDeviation() { | ||
return Math.sqrt(this.getPopulationVariance()); | ||
} | ||
|
||
public synchronized double getStandardError() { | ||
return this.getSampleStandardDeviation() / Math.sqrt((double) this.n); | ||
} | ||
|
||
public synchronized long getSampleSize() { | ||
return this.n; | ||
} | ||
|
||
public synchronized double getMin() { | ||
return this.min; | ||
} | ||
|
||
public synchronized double getMax() { | ||
return this.max; | ||
} | ||
|
||
public IoRequest newRequest() { | ||
return new IoRequest(); | ||
} | ||
|
||
public class IoRequest { | ||
|
||
long t0 = System.nanoTime(); | ||
|
||
private IoRequest() { | ||
} | ||
|
||
public void done(long size) { | ||
long delta = System.nanoTime() - t0; | ||
double bandwith = ((double) size / delta ) * TimeUnit.SECONDS.toNanos(1); | ||
update(bandwith); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
src/test/java/org/dcache/nearline/cta/xrootd/IoStatsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.dcache.nearline.cta.xrootd; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import org.dcache.util.ByteUnit; | ||
import org.dcache.util.ByteUnits; | ||
import org.junit.Test; | ||
|
||
public class IoStatsTest { | ||
|
||
|
||
private IoStats ioStats = new IoStats(); | ||
|
||
|
||
@Test | ||
public void testStats() throws InterruptedException { | ||
var stats = ioStats.newRequest(); | ||
|
||
var speedInMB = 300; | ||
var sleepTime = 5; // 5 sec | ||
|
||
TimeUnit.SECONDS.sleep(sleepTime); | ||
stats.done(ByteUnit.MB.toBytes(speedInMB) * sleepTime); | ||
|
||
// expected 300 MB/s | ||
assertEquals(speedInMB, ByteUnit.BYTES.toMB(ioStats.getMean()), 1.0); | ||
} | ||
|
||
} |