lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

Roberto Ierusalimschy wrote:
> Have anyone tried the LUA_GCSETINCMODE option? Ideally, the
> call
> 
>   collectgarbage(setincmode, 0)
> 
> should turn off the incremental collector. Therefore, Lua 5.1 should
> behave like 5.0. But it doesn't, and I haven't any clue why...

Umm, are you sure that it doesn't work?

I patched luaC_step to print some stats after each call (see attachment).

It prints the GC states before and after the loop, the number of calls to
singlestep(), the number of CPU cycles/2^10 (translates roughly to micro-
seconds on my machine), the step limit before and after the loop and the
GC threshold before and after the call.

I've tried a trivial example that piles up empty tables:

collectgarbage()
collectgarbage("setincmode", 0)     -- change this to 1 for incremental mode

local oldc = 0
for i=1,10000 do
  local x = {}                      -- pile up garbage
  local c = collectgarbage("count")
  if c ~= oldc then oldc = c; io.write(c, " ") end
end
io.write("\n")

Incremental mode:

...
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
*** pause|propg, st:   107, cyc:    23, lim:    8|  -1, thr:   32|  33
33
*** propg|swstr, st:   233, cyc:    20, lim:    8|  -1, thr:   33|  34
34
*** swstr|sweep, st:    87, cyc:    96, lim:    8|  -1, thr:   34|  29
28 29
*** sweep|sweep, st:    28, cyc:    55, lim:    8|  -1, thr:   29|  22
21 22
*** sweep|pause, st:    26, cyc:    22, lim:    8|   0, thr:   22|  32
19 20 21 22 23 24 25 26 27 28 29 30 31 32
*** pause|sweep, st:   259, cyc:    25, lim:    7|  -1, thr:   32|  32
31 32
*** sweep|sweep, st:    28, cyc:   156, lim:    8|  -1, thr:   32|  25
24 25
*** sweep|sweep, st:    28, cyc:    45, lim:    8|  -1, thr:   25|  19
18 19
*** sweep|pause, st:    11, cyc:     2, lim:    8|   5, thr:   19|  32
20 21 22 23 24 25 26 27 28 29 30 31 32
*** pause|sweep, st:   259, cyc:    25, lim:    7|  -1, thr:   32|  32
...

BTW: The jumps in the cycle counts are due to initial page faults and
     vanish a bit later when memory allocation has reached a stable state.

Non-incremental mode:

...
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
*** pause|pause, st:   475, cyc:   155, lim:    8| -31, thr:   32|  32
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
*** pause|pause, st:   475, cyc:   154, lim:    7| -31, thr:   32|  32
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
*** pause|pause, st:   475, cyc:   165, lim:    7| -31, thr:   32|  32
...

This looks both perfectly fine to me.

So ... do you have an example where the non-incremental mode fails?

Bye,
     Mike
--- lua-5.1-work4/src/lgc.c.orig	2004-12-13 13:15:11.000000000 +0100
+++ lua-5.1-work4/src/lgc.c	2005-01-07 04:21:57.305087200 +0100
@@ -620,10 +620,23 @@
 }
 
 
+static const char * const gcstab[] = {
+  "pause", "propg", "swstr", "sweep", "final"
+};
+
+#define rdtscll(v) __asm__ __volatile__ ("rdtsc" : "=A" (v))
+
 void luaC_step (lua_State *L) {
   global_State *g = G(L);
   l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * GCSTEPMUL;
+  int steps = 0;
+  l_mem olim = lim;
+  lu_mem othr = g->GCthreshold;
+  int ostate = g->gcstate;
+  unsigned long long start, stop;
+  rdtscll(start);
   do {
+    steps++;
     lim -= singlestep(L);
     if (g->gcstate == GCSpause)
       break;
@@ -634,6 +647,10 @@
     lua_assert(g->totalbytes >= g->estimate);
     g->GCthreshold = g->estimate + ((g->estimate/GCDIV) * g->gcpace);
   }
+  rdtscll(stop);
+  printf("\n*** %s|%s, st: %5d, cyc: %5lld, lim: %4d|%4d, thr: %4d|%4d\n",
+         gcstab[ostate], gcstab[g->gcstate], steps, (stop-start)>>10,
+         olim>>10, lim>>10, othr>>10, g->GCthreshold>>10);
 }