/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
import org.vmmagic.pragma.NoInline;
class FixedLive {
static int liveSize = 0; // in megabytes
static int checkFreq = 128 * 1024; // in bytes
static Node2I2A root;
static Node2I2A junk;
public static void main(String[] args) throws Throwable {
boolean base = true;
if (args.length == 0) {
System.out.println("No argument. Assuming base");
} else if (args[0].compareTo("opt") == 0 || args[0].compareTo("perf") == 0) {
base = false;
}
liveSize = base ? 30 : 100;
exclude = base ? 0 : 2;
sampleCount = -exclude;
if (liveSize < 0)
System.out.println("Amount of live data must be positive");
runTest();
System.exit(0);
}
static double setupTime = 0.0;
static double sumTraceTime = 0.0;
static double sumAllocTime = 0.0;
static double sumTraceRate = 0.0;
static double squaredSumTraceRate = 0.0;
static double sumAllocRate = 0.0;
static double squaredSumAllocRate = 0.0;
public static int exclude; // skips first two GCs
static int sampleCount;
public static void addSample(double traceElapsed, double allocElapsed,
double traceRate, double allocRate) {
sampleCount++;
System.out.print("GC occurred (" + traceElapsed + " s) after " + allocElapsed + "s : tracing rate = " + traceRate + " Mb/s");
System.out.print(" allocation rate = " + allocRate + " Mb/s");
if (sampleCount < 1) {
System.out.println(" <--- Skipping");
} else {
System.out.println();
sumTraceTime += traceElapsed;
sumAllocTime += allocElapsed;
sumTraceRate += traceRate;
sumAllocRate += allocRate;
squaredSumTraceRate += traceRate * traceRate;
squaredSumAllocRate += allocRate * allocRate;
}
}
static double avgTraceRate;
static double avgAllocRate;
static double diffSquaredSumTraceRate;
static double diffSquaredSumAllocRate;
static double rmsTraceRate;
static double rmsAllocRate;
static double zTraceRate;
static double zAllocRate;
public static double chop(double x) {
return ((int) (1000 * x) + 0.5) / 1000;
}
public static void updateStats() {
setupTime = chop(setupTime);
sumAllocTime = chop(sumAllocTime);
sumTraceTime = chop(sumTraceTime);
avgTraceRate = sumTraceRate / sampleCount;
avgAllocRate = sumAllocRate / sampleCount;
diffSquaredSumTraceRate = squaredSumTraceRate + sampleCount * (avgTraceRate * avgTraceRate) -
2 * avgTraceRate * sumTraceRate;
diffSquaredSumAllocRate = squaredSumAllocRate + sampleCount * (avgAllocRate * avgAllocRate) -
2 * avgAllocRate * sumAllocRate;
rmsTraceRate = Math.sqrt(diffSquaredSumTraceRate / sampleCount);
rmsAllocRate = Math.sqrt(diffSquaredSumAllocRate / sampleCount);
zTraceRate = rmsTraceRate / avgTraceRate;
zAllocRate = rmsAllocRate / avgAllocRate;
avgTraceRate = chop(avgTraceRate);
avgAllocRate = chop(avgAllocRate);
rmsTraceRate = chop(rmsTraceRate);
rmsAllocRate = chop(rmsAllocRate);
zTraceRate = chop(zTraceRate);
zAllocRate = chop(zAllocRate);
}
public static void showResults() {
updateStats();
System.out.println();
System.out.println(" Tracing rate: " + avgTraceRate + " Mb/s, sigma " + rmsTraceRate + " Mb/s, z-score " + zTraceRate);
System.out.println(" Allocation rate: " + avgAllocRate + " Mb/s, sigma " + rmsAllocRate + " Mb/s, z-score " + zAllocRate);
System.out.println();
System.out.println(" Total Setup Time: " + setupTime + " s");
System.out.println("Total Allocation Time: " + sumAllocTime + " s");
System.out.println(" Total Tracing Time: " + sumTraceTime + " s");
System.out.println();
System.out.println("Overall: SUCCESS");
}
// Allocate until either maxGC GC's have occurred or maxMb megabytes have been allocated
//
@NoInline
public static void allocateLoop(int count) {
for (int i=0; i<count; i++)
junk = new Node2I2A();
}
public static void allocateDie(int maxGC, int maxMb, double maxTime) {
int count = maxMb * ((1 << 20) / Node2I2A.objectSize);
long firstStart = System.currentTimeMillis();
System.out.println("Allocating " + maxMb + " Mb or until " + maxGC + " GCs have occurred or until we would exceed " + maxTime + " secs.");
System.out.println("First " + exclude + "GC's are excluded from overall statistics\n");
int checkFreqObj = checkFreq / Node2I2A.objectSize;
long last = System.currentTimeMillis();
double allocatedSize = 0;
for (int i=0; i< count / checkFreqObj && sampleCount < maxGC; i++) {
long start = System.currentTimeMillis();
allocateLoop(checkFreqObj);
allocatedSize += checkFreq;
long end = System.currentTimeMillis();
double traceElapsed = (end - start) / 1000.0;
double allocElapsed = (start - last) / 1000.0;
double totalElapsed = traceElapsed + allocElapsed;
if (traceElapsed > 0.1) {
double traceRate = chop(liveSize / traceElapsed); // Mb/s
double allocRate = chop((allocatedSize / 1e6) / allocElapsed); // Mb/s
addSample(traceElapsed, allocElapsed, traceRate, allocRate);
allocatedSize = 0;
last = end;
}
if (0.001 * (end - firstStart) + totalElapsed > maxTime)
break;
}
showResults();
}
public static void runTest() throws Throwable {
System.out.println("FixedLive running with " + liveSize + " Mb fixed live data\n");
long start = System.currentTimeMillis();
Node2I2A.computeObjectSize();
System.out.println("Estimated object size of a 4-field object (2 int, 2 ref) is " + Node2I2A.objectSize + " bytes");
System.out.println("Header size is probably " + (Node2I2A.objectSize - 16) + " bytes");
System.out.println("Note that the results of this test are not too meaningful for a generational collector");
int count = (liveSize << 20) / Node2I2A.objectSize;
System.out.println("Creating live data: tree with " + count + " nodes");
root = Node2I2A.createTree(count);
long end = System.currentTimeMillis();
setupTime = (end - start) / 1000.0;
allocateDie(5, 2048, 200.0);
}
}