Re: [rvm-research] ImmixConstants MAX_COLLECTORS value
Erik Brangs <[email protected]>
| Newsgroups | gmane.comp.java.jikes.rvm.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, On 30.05.2014 01:21, Jeremy Singer wrote: > I just compiled a production build of Jikes RVM on my shiny new 32 core x86_64-linux box. RVM built ok but when I ran it with the DaCapo avrora benchmark it died on the first major GC, failing this assertion: > > [snip] > at [0x70e52ee4, 0x64ec6f56] Lorg/jikesrvm/mm/mmtk/Assert; _assert(Z)V at line 55 > at [0x70e52ee4, 0x64ec6f56] Lorg/mmtk/policy/immix/ImmixSpace; prepare(Z)V at line 139 > > The assertion in ImmixSpace.java line 139 is: > > VM.activePlan.collectorCount() <= MAX_COLLECTORS > > I checked MAX_COLLECTORS, which is set to 16 in > MMTk/src/org/mmtk/policy/immix/ImmixConstants.java This seems to be issue RVM-953 ( http://jira.codehaus.org/browse/RVM-953 ). > My question is, should we automatically generate the value for MAX_COLLECTORS using something like Linux nproc at source code generation time? Or at least, flag this issue somewhere sensible so people know what's happening? You're assuming that a VM image is built on the target machine. This doesn't have to be true. Moreover, the collector threads are spawned at run time so it is not necessary to know the exact number of collector threads at build time. I'd rather see a fix to the Immix collectors that makes it possible to use more threads. IMHO a fix that automatically adjusts the number of collector threads would be the next best option if that's not possible. I'm attaching a rough patch for the latter to this mail. It's based on your patch for RVM-953. > I guess this issue may trip up a number of unsuspecting people, especially as core counts are increasing. There's certainly enough work to do to make the Jikes RVM suitable for use on machines with many cores. Kind regards, Erik Brangs ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/NeoTech _______________________________________________ Jikesrvm-researchers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/jikesrvm-researchers
untested-sketch-rvm-953-restrict-collector-thread-count.diff
(text/x-patch, 5.3 KB)
diff --git a/MMTk/src/org/mmtk/plan/Plan.java b/MMTk/src/org/mmtk/plan/Plan.java
--- a/MMTk/src/org/mmtk/plan/Plan.java
+++ b/MMTk/src/org/mmtk/plan/Plan.java
@@ -238,15 +238,47 @@
*/
@Interruptible
public void enableCollection() {
+ int defaultThreadCount = VM.collection.getDefaultThreads();
+ int maxThreadCount = VM.activePlan.constraints().maxNumGCThreads();
+ int safeDefaultValue = Math.min(defaultThreadCount, maxThreadCount);
+
// Make sure that if we have not explicitly set threads, then we use the right default.
- Options.threads.updateDefaultValue(VM.collection.getDefaultThreads());
+ if (Options.verbose.getValue() > 0) {
+ Log.write("Setting default thread count for MMTk to minimum of ");
+ Log.write("default thread count ");
+ Log.write(defaultThreadCount);
+ Log.write(" and maximal thread count ");
+ Log.write(maxThreadCount);
+ Log.write(" supported by current GC plan.");
+ Log.writeln();
+ Log.write("New default thread count value is ");
+ Log.write(safeDefaultValue);
+ Log.writeln();
+ }
+ Options.threads.updateDefaultValue(safeDefaultValue);
+
+ int desiredThreadCount = Options.threads.getValue();
+ int actualThreadCount = Math.min(desiredThreadCount, maxThreadCount);
+ if (Options.verbose.getValue() > 0) {
+ Log.write("Setting actual thread count for MMTk to minimum of ");
+ Log.write("desired thread count ");
+ Log.write(desiredThreadCount);
+ Log.write(" and maximal thread count ");
+ Log.write(maxThreadCount);
+ Log.write(" supported by current GC plan.");
+ Log.writeln();
+ Log.write("New actual thread count is ");
+ Log.write(actualThreadCount);
+ Log.writeln();
+ }
+ Options.threads.setValue(actualThreadCount);
// Create our parallel workers
- parallelWorkers.initGroup(Options.threads.getValue(), defaultCollectorContext);
+ parallelWorkers.initGroup(actualThreadCount, defaultCollectorContext);
// Create the concurrent worker threads.
if (VM.activePlan.constraints().needsConcurrentWorkers()) {
- concurrentWorkers.initGroup(Options.threads.getValue(), defaultCollectorContext);
+ concurrentWorkers.initGroup(actualThreadCount, defaultCollectorContext);
}
// Create our control thread.
diff --git a/MMTk/src/org/mmtk/plan/PlanConstraints.java b/MMTk/src/org/mmtk/plan/PlanConstraints.java
--- a/MMTk/src/org/mmtk/plan/PlanConstraints.java
+++ b/MMTk/src/org/mmtk/plan/PlanConstraints.java
@@ -190,4 +190,10 @@
/** @return {@code true} if this Plan requires a header bit for object logging */
public boolean needsLogBitInHeader() { return false; }
+
+ /**
+ * @return Maximum number of GC threads supported by this GC plan.
+ * The return value is always a non-negative number.
+ */
+ public int maxNumGCThreads() { return Integer.MAX_VALUE; }
}
diff --git a/MMTk/src/org/mmtk/plan/generational/immix/GenImmixConstraints.java b/MMTk/src/org/mmtk/plan/generational/immix/GenImmixConstraints.java
--- a/MMTk/src/org/mmtk/plan/generational/immix/GenImmixConstraints.java
+++ b/MMTk/src/org/mmtk/plan/generational/immix/GenImmixConstraints.java
@@ -14,6 +14,7 @@
import org.mmtk.plan.generational.GenConstraints;
import static org.mmtk.policy.immix.ImmixConstants.MAX_IMMIX_OBJECT_BYTES;
+import static org.mmtk.policy.immix.ImmixConstants.MAX_COLLECTORS;
import org.vmmagic.pragma.*;
@@ -30,4 +31,6 @@
public int numSpecializedScans() { return 2; }
@Override
public int maxNonLOSCopyBytes() { return MAX_IMMIX_OBJECT_BYTES;}
+ @Override
+ public int maxNumGCThreads() { return MAX_COLLECTORS; }
}
diff --git a/MMTk/src/org/mmtk/plan/immix/ImmixConstraints.java b/MMTk/src/org/mmtk/plan/immix/ImmixConstraints.java
--- a/MMTk/src/org/mmtk/plan/immix/ImmixConstraints.java
+++ b/MMTk/src/org/mmtk/plan/immix/ImmixConstraints.java
@@ -15,6 +15,7 @@
import org.mmtk.plan.StopTheWorldConstraints;
import org.mmtk.policy.immix.ObjectHeader;
import static org.mmtk.policy.immix.ImmixConstants.MAX_IMMIX_OBJECT_BYTES;
+import static org.mmtk.policy.immix.ImmixConstants.MAX_COLLECTORS;
import org.vmmagic.pragma.*;
@@ -44,4 +45,7 @@
@Override
public int maxNonLOSCopyBytes() { return MAX_IMMIX_OBJECT_BYTES; }
+
+ @Override
+ public int maxNumGCThreads() { return MAX_COLLECTORS; }
}
diff --git a/MMTk/src/org/mmtk/policy/immix/ImmixConstants.java b/MMTk/src/org/mmtk/policy/immix/ImmixConstants.java
--- a/MMTk/src/org/mmtk/policy/immix/ImmixConstants.java
+++ b/MMTk/src/org/mmtk/policy/immix/ImmixConstants.java
@@ -68,7 +68,7 @@
static final short MAX_CONSV_SPILL_COUNT = (short) (LINES_IN_BLOCK/2);
public static final short SPILL_HISTOGRAM_BUCKETS = (short) (MAX_CONSV_SPILL_COUNT + 1);
public static final short MARK_HISTOGRAM_BUCKETS = (short) (LINES_IN_BLOCK + 1);
- static final short MAX_COLLECTORS = 16; // nothing special here---we can increase this at the cost of a few hundred bites at build time.
+ public static final short MAX_COLLECTORS = 16; // nothing special here---we can increase this at the cost of a few hundred bytes at build time.
public static final Word RECYCLE_ALLOC_CHUNK_MASK = Word.fromIntZeroExtend(BYTES_IN_RECYCLE_ALLOC_CHUNK - 1);
protected static final Word CHUNK_MASK = Word.fromIntZeroExtend(BYTES_IN_CHUNK - 1);