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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.