lua-users home
lua-l archive

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


Lua version 5.3.0
In each gc step,
luaC_step() call singlestep() in while loop until debt reduce to -GCSTEPSIZE,

singlestep() return the bytes haved processed:
1.in propagate state, it return the bytes traversed(marked);
2.in sweep state, it return a estimate value: GCSWEEPMAX * GCSWEEPCOST;

In a 64bits Debian Linux system, GCSWEEPCOST is 7 bytes,
which is much smaller than any kind GCObject(TString, Udata, ...).
After each call to singlestep(), debt reduce GCSWEEPMAX * GCSWEEPCOST,
until to -GCSTEPSIZE.
So the GCSWEEPCOST much smaller,
the times of execute singlestep() is much more,
i.e., the speed of sweep(free) is much faster;

In our program, collectgarbage("count") is 10G at the end of propagate state,
while gc switch to sweep state, gc system free 5G bytes in only 30 seconds,
and the usage of CPU is 99.9% during the whole 30 seconds sweep state;

If I adjust GCSWEEPCOST to a larger value,
the time of sweep state becomes long,
and CPU's usage becomes lower.
But it is a little difficult to adjust GCSWEEPCOST to a fit value;

I am curious about why sweepstep() doesn't return the real free bytes, i.e, olddebt - g->GCdebt ?
Thanks.

1011 static lu_mem sweepstep (lua_State *L, global_State *g,
1012                          int nextstate, GCObject **nextlist) {
1013         if (g->sweepgc) {
1014                 l_mem olddebt = g->GCdebt;
1015                 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1016                 g->GCestimate += g->GCdebt - olddebt;  /* update estimate */
1017                 if (g->sweepgc)  /* is there still something to sweep? */
1018                         return (GCSWEEPMAX * GCSWEEPCOST);
1019         }
             ...
     }

1109 void luaC_step (lua_State *L) {
1110         global_State *g = G(L);
1111         l_mem debt = getdebt(g);  /* GC deficit (be paid now) */
1112         if (!g->gcrunning) {  /* not running? */
1113                 luaE_setdebt(g, -GCSTEPSIZE * 10);  /* avoid being called too often */
1114                 return;
1115         }
1116         do {  /* repeat until pause or enough "credit" (negative debt) */
1117                 lu_mem work = singlestep(L);  /* perform one single step */
1118                 debt -= work;
1119         } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1120         if (g->gcstate == GCSpause)
1121                 setpause(g);  /* pause until next cycle */
1122         else {
1123                 debt = (debt / g->gcstepmul) * STEPMULADJ;  /* convert 'work units' to Kb */
1124                 luaE_setdebt(g, debt);
1125                 runafewfinalizers(L);
1126         }

1127 }


Best Regards
John Wei