diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java index f7b9ac08..f8e2ef68 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java @@ -51,15 +51,14 @@ public class Options { private String resultDir; private String testFilter; private int minStride, maxStride; - private int maxFootprint; private int time; private int iters; private final String[] args; private boolean parse; private boolean list; private Verbosity verbosity; - private int totalCpuCount; private int cpuCount; + private int heapPerFork; private int forks; private String mode; private SpinLoopStyle spinStyle; @@ -107,7 +106,7 @@ public boolean parse() throws IOException { "Reducing the number of CPUs limits the amount of resources (including memory) the run is using.") .withRequiredArg().ofType(Integer.class).describedAs("N"); - OptionSpec<Integer> maxFootprint = parser.accepts("mf", "Maximum footprint for each test, in megabytes. This " + + OptionSpec<Integer> heapPerFork = parser.accepts("hs", "Java heap size per fork, in megabytes. This " + "affects the stride size: maximum footprint will never be exceeded, regardless of min/max stride sizes.") .withRequiredArg().ofType(Integer.class).describedAs("MB"); @@ -181,7 +180,7 @@ public boolean parse() throws IOException { this.verbosity = new Verbosity(0); } - totalCpuCount = VMSupport.figureOutHotCPUs(); + int totalCpuCount = VMSupport.figureOutHotCPUs(); cpuCount = orDefault(set.valueOf(cpus), totalCpuCount); if (cpuCount > totalCpuCount) { @@ -236,7 +235,7 @@ public boolean parse() throws IOException { this.minStride = orDefault(set.valueOf(minStride), 10); this.maxStride = orDefault(set.valueOf(maxStride), 10000); - this.maxFootprint = orDefault(set.valueOf(maxFootprint), 100); + this.heapPerFork = orDefault(set.valueOf(heapPerFork), 256); this.jvmArgs = processArgs(optJvmArgs, set); this.jvmArgsPrepend = processArgs(optJvmArgsPrepend, set); @@ -345,10 +344,6 @@ public int getCPUCount() { return cpuCount; } - public int getTotalCPUCount() { - return totalCpuCount; - } - public String getResultFile() { return resultFile; } @@ -361,8 +356,13 @@ public Collection<String> getJvmArgsPrepend() { return jvmArgsPrepend; } + public int getHeapPerForkMb() { + return heapPerFork; + } + public int getMaxFootprintMb() { - return maxFootprint; + // Half of heap size. + return getHeapPerForkMb() / 2; } } diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java index 2a2f5c13..f835b049 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java @@ -209,11 +209,6 @@ private static boolean skipMessage(String data) { return true; } - if (data.contains("Option MaxRAMFraction was deprecated in version") || - data.contains("Option MinRAMFraction was deprecated in version")) { - return true; - } - if (data.contains("compiler directives added")) { return true; } diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java index 9bbe0b30..a18e0bfb 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java @@ -72,46 +72,51 @@ public static void initFlags(Options opts) { "-XX:+UnlockDiagnosticVMOptions" ); - // Rationale: every test VM uses at least 2 threads. Which means there are at max $CPU/2 VMs. - // Reserving half of the RSS of each VM to Java heap leaves enough space for native RSS and - // other processes. This means multiplying the factor by 2. These two adjustments cancel each - // other. - // - // It does not matter if user requested lower number of VMs, we still want to follow - // the global per-VM fraction. This would trim down the memory requirements along with - // CPU requirements. - // - // Setting -Xms/-Xmx explicitly is supposed to override these defaults. - // - int part = opts.getTotalCPUCount(); - - detect("Trimming down the default VM heap size to 1/" + part + "-th of max RAM", + // Tests are supposed to run in a very tight memory constraints: + // the test objects are small and reused where possible. The footprint + // testing machinery would select appropriate stride sizes to fit the heap. + // Users can override this to work on smaller/larger machines, but it should + // not be necessary, as even the smallest machines usually have more than 256M + // of system memory per CPU. + + int heap = opts.getHeapPerForkMb(); + detect("Trimming down the VM heap size to " + heap + "M", SimpleTestMain.class, GLOBAL_JVM_FLAGS, - "-XX:MaxRAMFraction=" + part, "-XX:MinRAMFraction=" + part); + "-Xms" + heap + "M", "-Xmx" + heap + "M"); - detect("Trimming down the number of compiler threads", - SimpleTestMain.class, - GLOBAL_JVM_FLAGS, - "-XX:CICompilerCount=2" // This is the absolute minimum for tiered configurations - ); + // The tests are usually not GC heavy. The minimum amount of threads a jcstress + // test uses is 2, so we can expect the CPU affinity machinery to allocate at + // least 2 CPUs per fork. This gives us the upper bound for the number of GC threads: 2, + // otherwise we risk oversubscribing the forked VM. + // + // We could, theoretically, drop the number of GC threads to 1, but GC ergonomics + // sometimes decides to switch to single-threaded mode in some GC implementations + // (e.g. for reference processing), and it would make sense to let GC run in multi-threaded + // modes instead. detect("Trimming down the number of parallel GC threads", SimpleTestMain.class, GLOBAL_JVM_FLAGS, - "-XX:ParallelGCThreads=4" + "-XX:ParallelGCThreads=2" ); detect("Trimming down the number of concurrent GC threads", SimpleTestMain.class, GLOBAL_JVM_FLAGS, - "-XX:ConcGCThreads=4" + "-XX:ConcGCThreads=2" ); detect("Trimming down the number of G1 concurrent refinement GC threads", SimpleTestMain.class, GLOBAL_JVM_FLAGS, - "-XX:G1ConcRefinementThreads=4" + "-XX:G1ConcRefinementThreads=2" + ); + + detect("Trimming down the number of compiler threads", + SimpleTestMain.class, + GLOBAL_JVM_FLAGS, + "-XX:CICompilerCount=2" // This is the absolute minimum for tiered configurations ); detect("Testing @Contended works on all results and infra objects",