Changeset: 804494acbe59 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=804494acbe59
Modified Files:
        monetdb5/mal/mal_recycle.c
Branch: default
Log Message:

First attempt to respect main memory limits during recycling


diffs (171 lines):

diff --git a/monetdb5/mal/mal_recycle.c b/monetdb5/mal/mal_recycle.c
--- a/monetdb5/mal/mal_recycle.c
+++ b/monetdb5/mal/mal_recycle.c
@@ -260,7 +260,7 @@ int chooseVictims(Client cntxt, int *lea
 }
 
 
-static void RECYCLEcleanCache(Client cntxt, lng wr0,lng clk){
+static void RECYCLEcleanCache(Client cntxt, lng clk){
        int j,i,l,ltop,v,vtop;
        InstrPtr p;
        InstrPtr *old, *newstmt;
@@ -269,16 +269,21 @@ static void RECYCLEcleanCache(Client cnt
        int limit, idx;
        size_t mem;
        int cont;
-       lng oldclk, wr;
+       lng oldclk,wr;
        dbl minben, ben;
        bte *used;
 
-       if (!recycleBlk)
+       assert(recycleBlk);
+newpass:
+       if (recycleBlk->stop == 0)
                return;
+       cont = 0;
+       wr = GDKmem_cursize() -  MEMORY_THRESHOLD * monet_memory;
+       if ( wr < 0 && recycleBlk->stop < recycleCacheLimit)
+               return;
+       if ( wr < 0)
+               wr=0;
 
-newpass:
-       cont = 0;
-       wr = wr0;
        used = (bte*)GDKzalloc(recycleBlk->vtop);
 
        /* set all variables used */
@@ -300,21 +305,21 @@ newpass:
                skip:;
        }
 
-
        if (ltop == 0 ){  
                GDKfree(lmask);
                return;
        }
        leaves = (int *)GDKzalloc(sizeof(int)*ltop);
        l = 0;
-       for (i = 0; i < recycleBlk->stop; i++)
+       for (i = 0; i < recycleBlk->stop; i++){
                if (lmask[i]) leaves[l++] = i;
+       }
        GDKfree(lmask);
 
        /* find the oldest leave */
        oldclk = recycleBlk->profiler[leaves[0]].clk;
        idx = 0;
-       for (l = 0; l < ltop; l++){
+       for (l = 1; l < ltop; l++){
                k = leaves[l];
                if( recycleBlk->profiler[k].clk < oldclk){
                        oldclk = recycleBlk->profiler[k].clk;
@@ -333,7 +338,7 @@ newpass:
 
 
 #ifdef _DEBUG_CACHE_
-        mnstr_printf(cntxt->fdout,"#RECYCLEcleanCache: usedmem="LLFMT" target 
memory freed "LLFMT"\n", recyclerMemoryUsed,wr);
+        mnstr_printf(cntxt->fdout,"#RECYCLEcleanCache: usedmem="LLFMT" target 
memory freed "LLFMT"\n", recyclerMemoryUsed, wr);
         mnstr_printf(cntxt->fdout,"#Candidates for 
eviction\n#LRU\t\tTicks\tLife\tSZ\tCnt\tWgt\tBen\tProf)\n");
                for (l = 0; l < ltop; l++)
                mnstr_printf(cntxt->fdout,"#%3d "LLFMT"\t"LLFMT"\t"LLFMT"\t 
%5.2f\t "LLFMT"\t%3d\t%5.1f\n",
@@ -346,7 +351,7 @@ newpass:
 #endif
 
        /* find entries to evict */
-       mem = (size_t)(recyclerMemoryUsed + wr) > monet_memory ;
+       mem = (size_t)recyclerMemoryUsed  > MEMORY_THRESHOLD * monet_memory ;
        vm = (int *)GDKzalloc(sizeof(int)*ltop);
        vtop = 0;
 
@@ -363,20 +368,25 @@ newpass:
                vm[vtop++] = leaves[idx];
        } else {        /* evict several to get enough memory */
                k = 0;  /* exclude binds that don't free memory */
-               for (l = 0; l < ltop; l++)
+               for (l = 0; l < ltop; l++) {
+                       // also discard leaves that are more expensive to find 
then compute
+                       if( recycleBlk->profiler[leaves[l]].ticks < 
recycleSearchTime)
+                               continue;
                        if ( recycleBlk->profiler[leaves[l]].wbytes > 0 )
                                leaves[k++] = leaves[l];
+               }
                if ( k > 0 )
                        ltop = k;
-               vtop = chooseVictims(cntxt,leaves, ltop, recyclerMemoryUsed + 
wr - monet_memory );
+               vtop = chooseVictims(cntxt,leaves, ltop, (wr<0?0:wr) );
+               wr=0;
                for (v = 0; v < vtop; v++){
                        vm[v] = leaves[v];
-                       wr -= recycleBlk->profiler[leaves[v]].wbytes;
+                       wr += recycleBlk->profiler[leaves[v]].wbytes;
                }
        }
 
        /* check if a new pass of cache cleaning is needed */
-       if ( (size_t)(recyclerMemoryUsed + wr) > monet_memory )
+       if ( (size_t)(recyclerMemoryUsed - wr) > MEMORY_THRESHOLD * 
monet_memory )
                cont = 1;
 
 #ifdef _DEBUG_CACHE_
@@ -476,7 +486,7 @@ RECYCLEkeep(Client cntxt, MalBlkPtr mb, 
 
        if ( recycleBlk->stop >= recycleCacheLimit)
                return ; /* no more caching */
-       if ( (size_t)(recyclerMemoryUsed + wr) > monet_memory)
+       if ( (size_t)(recyclerMemoryUsed + wr) > MEMORY_THRESHOLD * 
monet_memory)
                return ; /* no more caching */
 
        /*
@@ -862,7 +872,6 @@ RECYCLEreuse(Client cntxt, MalBlkPtr mb,
         p->recycle= k;
         stk->keepAlive= j;
         BBPdecref(bid, TRUE);
-               recycled++;
         recycleBlk->profiler[pc].calls++;
         recycleBlk->profiler[pc].clk = GDKusec();
         MT_lock_unset(&recycleLock, "recycle");
@@ -874,6 +883,7 @@ RECYCLEreuse(Client cntxt, MalBlkPtr mb,
     MT_lock_unset(&recycleLock, "recycle");
        if ( pc >= 0 )          /* successful multi-subsumption */
                RECYCLEexitImpl(cntxt,mb,stk,p, outerprof);
+       recycled++;
     return pc;
 }
 
@@ -905,22 +915,17 @@ RECYCLEentry(Client cntxt, MalBlkPtr mb,
 /*
  * The 'exit' instruction is called after the interpreter loop
  * itself and has to decide on the results obtained.
- * It can use the timing information gathered from the previous call,
- * which is stored in the stack frame to avoid concurrency problems.
+ * We simply look at the memory footprint to ensure it remains low
  */
 void
 RECYCLEexitImpl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p, 
RuntimeProfile prof)
 {
-       size_t wr;
 
-       if ( (wr =(size_t)mb->profiler[prof->stkpc].wbytes) > monet_memory)
-               return;
        if (recycleBlk == NULL || mb->profiler == NULL)
                return;
 
        MT_lock_set(&recycleLock, "recycle");
-       if ( (size_t)(recyclerMemoryUsed +  wr) > monet_memory  || 
recycleBlk->stop >= recycleCacheLimit)
-               RECYCLEcleanCache(cntxt, wr, mb->profiler[0].clk);
+       RECYCLEcleanCache(cntxt, mb->profiler[0].clk);
 
        if ( RECYCLEinterest(p)){
                /* infinite case, admit all new instructions */
@@ -933,7 +938,7 @@ RECYCLEexitImpl(Client cntxt, MalBlkPtr 
 void
 RECYCLEexit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p, 
RuntimeProfile prof)
 {
-       if (mb->profiler == 0) 
+       if (!RECYCLEinterest(p))
                return;
        RECYCLEexitImpl(cntxt,mb,stk,p,prof);
 }
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to