Skip to content

Commit

Permalink
ENHANCED: incrementally track dirty clause count to avoid O(N) cost w…
Browse files Browse the repository at this point in the history
…hen considering clause GC
  • Loading branch information
keriharris committed Jun 19, 2019
1 parent 22d227c commit 7c960e3
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/pl-global.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ struct PL_global_data
int64_t cgc_count; /* # clause GC calls */
int64_t cgc_reclaimed; /* # clauses reclaimed */
double cgc_time; /* Total time spent in CGC */
size_t dirty; /* # dirty clauses */
size_t erased; /* # erased pending clauses */
size_t erased_size; /* memory used by them */
size_t erased_size_last; /* memory used by them after last CGC */
Expand Down
47 changes: 16 additions & 31 deletions src/pl-proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ static void freeClauseRef(ClauseRef cref);
static int setDynamicDefinition_unlocked(Definition def, bool isdyn);
static void registerDirtyDefinition(Definition def ARG_LD);
static void unregisterDirtyDefinition(Definition def);
static size_t clause_count_in_dirty_predicates(ARG1_LD);

/* Enforcing this limit demands we propagate NULL from lookupProcedure()
through the whole system. This is not done
Expand Down Expand Up @@ -264,6 +263,9 @@ resetProcedure(Procedure proc, bool isnew)
!def->impl.any.defined )
isnew = TRUE;

if ( true(def, P_DIRTYREG) )
ATOMIC_SUB(&GD->clauses.dirty, def->impl.clauses.number_of_clauses);

def->flags ^= def->flags & ~(SPY_ME|P_DIRTYREG);
if ( stringAtom(def->functor->name)[0] != '$' )
set(def, TRACE_ME);
Expand Down Expand Up @@ -1219,6 +1221,8 @@ assertProcedure(Procedure proc, Clause clause, ClauseRef where ARG_LD)
if ( false(clause, UNIT_CLAUSE) )
def->impl.clauses.number_of_rules++;
ATOMIC_INC(&GD->statistics.clauses);
if ( true(def, P_DIRTYREG) )
ATOMIC_INC(&GD->clauses.dirty);
#ifdef O_LOGICAL_UPDATE
clause->generation.created = next_global_generation();
clause->generation.erased = GEN_MAX; /* infinite */
Expand Down Expand Up @@ -1339,6 +1343,8 @@ removeClausesPredicate(Definition def, int sfindex, int fromfile)
{ ATOMIC_SUB(&def->module->code_size, memory);
ATOMIC_ADD(&GD->clauses.erased_size, memory);
ATOMIC_ADD(&GD->clauses.erased, deleted);
if( true(def, P_DIRTYREG) )
ATOMIC_SUB(&GD->clauses.dirty, deleted);

registerDirtyDefinition(def PASS_LD);
DEBUG(CHK_SECURE, checkDefinition(def));
Expand Down Expand Up @@ -1386,6 +1392,8 @@ retractClauseDefinition(Definition def, Clause clause)
ATOMIC_SUB(&def->module->code_size, size);
ATOMIC_ADD(&GD->clauses.erased_size, size);
ATOMIC_INC(&GD->clauses.erased);
if( true(def, P_DIRTYREG) )
ATOMIC_DEC(&GD->clauses.dirty);

registerDirtyDefinition(def PASS_LD);

Expand Down Expand Up @@ -1640,6 +1648,8 @@ reconsultFinalizePredicate(sf_reload *rl, Definition def, p_reload *r ARG_LD)
{ ATOMIC_SUB(&def->module->code_size, memory);
ATOMIC_ADD(&GD->clauses.erased_size, memory);
ATOMIC_ADD(&GD->clauses.erased, deleted);
if( true(def, P_DIRTYREG) )
ATOMIC_SUB(&GD->clauses.dirty, deleted);

registerDirtyDefinition(def PASS_LD);
}
Expand Down Expand Up @@ -1949,7 +1959,7 @@ considerClauseGC(ARG1_LD)

LD->clauses.cgc_inferences = LD->statistics.inferences + 500;

stats.dirty_pred_clauses = clause_count_in_dirty_predicates(PASS_LD1);
stats.dirty_pred_clauses = GD->clauses.dirty;
if ( stats.dirty_pred_clauses == (size_t)-1 )
return FALSE; /* already clicked in */

Expand Down Expand Up @@ -2005,7 +2015,9 @@ registerDirtyDefinition(Definition def ARG_LD)

ddi->oldest_generation = GEN_NEW_DIRTY; /* see (*) */
if ( addHTable(GD->procedures.dirty, def, ddi) == ddi )
set(def, P_DIRTYREG);
{ set(def, P_DIRTYREG);
ATOMIC_ADD(&GD->clauses.dirty, def->impl.clauses.number_of_clauses);
}
else
PL_free(ddi); /* someone else did this */
}
Expand All @@ -2022,6 +2034,7 @@ unregisterDirtyDefinition(Definition def)
if ( (ddi=deleteHTable(GD->procedures.dirty, def)) )
{ PL_free(ddi);
clear(def, P_DIRTYREG);
ATOMIC_SUB(&GD->clauses.dirty, def->impl.clauses.number_of_clauses);
}
}

Expand All @@ -2045,34 +2058,6 @@ maybeUnregisterDirtyDefinition(Definition def)
}


static int
sum_dirty_clauses(void *n, size_t *countp)
{ Definition def = n;

if ( GD->clauses.cgc_active )
{ *countp = (size_t)-1;
return FALSE;
}

if ( false(def, P_FOREIGN) &&
def->impl.clauses.erased_clauses > 0 )
*countp += def->impl.clauses.number_of_clauses;

return TRUE;
}


static size_t
clause_count_in_dirty_predicates(ARG1_LD)
{ size_t ccount = 0;

for_table_as_long_as(GD->procedures.dirty, n, v,
sum_dirty_clauses(n, &ccount));

return ccount;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(*) We set the initial generation to GEN_MAX to know which predicates
have been marked. We can only reclaim clauses that were erased before
Expand Down

0 comments on commit 7c960e3

Please sign in to comment.