Classify overflowed sparks separately
authorDuncan Coutts <duncan@well-typed.com>
Wed, 1 Jun 2011 18:48:15 +0000 (19:48 +0100)
committerDuncan Coutts <duncan@well-typed.com>
Mon, 18 Jul 2011 15:31:14 +0000 (16:31 +0100)
When you use `par` to make a spark, if the spark pool on the current
capability is full then the spark is discarded. This represents a
loss of potential parallelism and it also means there are simply a
lot of sparks around. Both are things that might be of concern to a
programmer when tuning a parallel program that uses par.

The "+RTS -s" stats command now reports overflowed sparks, e.g.
SPARKS: 100001 (15521 converted, 84480 overflowed, 0 dud, 0 GC'd, 0 fizzled)

rts/Capability.c
rts/Sparks.c
rts/Sparks.h
rts/Stats.c

index e12bf99..d93c9c1 100644 (file)
@@ -234,6 +234,7 @@ initCapability( Capability *cap, nat i )
     cap->inbox              = (Message*)END_TSO_QUEUE;
     cap->spark_stats.created    = 0;
     cap->spark_stats.dud        = 0;
+    cap->spark_stats.overflowed = 0;
     cap->spark_stats.converted  = 0;
     cap->spark_stats.gcd        = 0;
     cap->spark_stats.fizzled    = 0;
index d358ae6..26b8199 100644 (file)
@@ -64,8 +64,12 @@ newSpark (StgRegTable *reg, StgClosure *p)
     SparkPool *pool = cap->sparks;
 
     if (!fizzledSpark(p)) {
-        pushWSDeque(pool,p);
-        cap->spark_stats.created++;
+        if (pushWSDeque(pool,p)) {
+           cap->spark_stats.created++;
+        } else {
+            /* overflowing the spark pool */
+            cap->spark_stats.overflowed++;
+       }
     } else {
         cap->spark_stats.dud++;
     }
index c987a94..ea7d356 100644 (file)
@@ -19,6 +19,7 @@
 typedef struct {
     StgWord created;
     StgWord dud;
+    StgWord overflowed;
     StgWord converted;
     StgWord gcd;
     StgWord fizzled;
index 04b091c..7c02b5a 100644 (file)
@@ -629,18 +629,19 @@ stat_exit(int alloc)
 
             {
                 nat i;
-                SparkCounters sparks = { 0, 0, 0, 0, 0};
+                SparkCounters sparks = { 0, 0, 0, 0, 0, 0};
                 for (i = 0; i < n_capabilities; i++) {
                     sparks.created   += capabilities[i].spark_stats.created;
                     sparks.dud       += capabilities[i].spark_stats.dud;
+                    sparks.overflowed+= capabilities[i].spark_stats.overflowed;
                     sparks.converted += capabilities[i].spark_stats.converted;
                     sparks.gcd       += capabilities[i].spark_stats.gcd;
                     sparks.fizzled   += capabilities[i].spark_stats.fizzled;
                 }
 
-                statsPrintf("  SPARKS: %ld (%ld converted, %ld dud, %ld GC'd, %ld fizzled)\n\n",
-                            sparks.created + sparks.dud,
-                            sparks.converted, sparks.dud,
+                statsPrintf("  SPARKS: %ld (%ld converted, %ld overflowed, %ld dud, %ld GC'd, %ld fizzled)\n\n",
+                            sparks.created + sparks.dud + sparks.overflowed,
+                            sparks.converted, sparks.overflowed, sparks.dud,
                             sparks.gcd, sparks.fizzled);
             }
 #endif