diff --git a/src/vault/mem/local-mem-pool.hpp b/src/vault/mem/local-mem-pool.hpp index 0a518406a..849d689b2 100644 --- a/src/vault/mem/local-mem-pool.hpp +++ b/src/vault/mem/local-mem-pool.hpp @@ -100,6 +100,7 @@ namespace mem { using std::move; using std::forward; using std::invocable; + using util::max; using util::unConst; using util::isLimited; using std::this_thread::sleep_for; @@ -147,6 +148,7 @@ namespace mem { BlockList blocks_; int32_t maxScore_{1}; + int32_t turnover_{0}; std::function shutdownHook_{}; @@ -201,6 +203,13 @@ namespace mem { return bool(anyFree (sizRequest)); } + /** turnover-based trigger for heuristic pool clean-up */ + bool + shouldCleanup (float sharpen =1.0f) const + { + return turnover_ * float(MATCH_SCORE) <= maxScore_ * sharpen; + } + /** * Determine to what extent the indicated allocation request * could be handled, given the current memory available in the pool. @@ -252,6 +261,8 @@ namespace mem { { Alloc alloc{mem,siz}; AllocReceiver::supply (alloc); + if (alloc.mem) + ++turnover_; } /** @@ -264,7 +275,10 @@ namespace mem { supplyImmediately (Alloc alloc) { if (alloc.mem) - blocks_.emplace_front (move(alloc)); + { + blocks_.emplace_front (move(alloc)); + ++turnover_; + } // otherwise: allocation not serviced, do not add anything } @@ -285,6 +299,7 @@ namespace mem { throw err::Logic{"returning known allocation that is not marked as used"}; block->used = false; ENSURE (not block->resd); + --turnover_; } /** @@ -325,7 +340,11 @@ namespace mem { yield (uint cnt, size_t siz, FUN&& consumer) { ingest(); + if (blocks_.empty()) + return 0; + uint remain{0}; uint removed{0}; + int32_t newMax{0}; for (auto pos = blocks_.begin() ; pos != blocks_.end() ; ) @@ -341,8 +360,16 @@ namespace mem { --cnt; } else - ++pos; - + { + newMax = max (newMax, pos->score); + ++remain; + ++pos; + } + // recalibrate proportionally + uint prevSiz{removed+remain}; + ENSURE (0 < prevSiz); + turnover_ *= float(remain)/prevSiz; + maxScore_ = max (newMax,1); return removed; } @@ -359,6 +386,7 @@ namespace mem { cleanup (double degree, FUN&& consumer) { ingest(); + uint remain{0}; uint removed{0}; int32_t killLevel = degree * maxScore_; for (auto pos = blocks_.begin() @@ -373,12 +401,14 @@ namespace mem { } else { + ++remain; pos->score -= killLevel; ++pos; } // recalibrate all score levels maxScore_ -= killLevel; - maxScore_ = util::max (maxScore_, 1); + maxScore_ = max (maxScore_, 1); + turnover_ = remain; return removed; } @@ -545,6 +575,18 @@ namespace mem { REQUIRE (entry, "Test refers to entry unknown in pool"); return entry->score; } + + int32_t + getMaxScore() + { + return memPool_.maxScore_; + } + + int32_t + getTurnover() + { + return memPool_.turnover_; + } }; diff --git a/tests/vault/mem/local-mem-pool-test.cpp b/tests/vault/mem/local-mem-pool-test.cpp index 35b953c72..b17798a47 100644 --- a/tests/vault/mem/local-mem-pool-test.cpp +++ b/tests/vault/mem/local-mem-pool-test.cpp @@ -379,36 +379,205 @@ namespace test { SHOW_EXPR(show(globalPool)); SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) supply(3); +SHOW_EXPR("supply") SHOW_EXPR(show(globalPool)); SHOW_EXPR(watch(pool).size()) SHOW_EXPR(watch(pool).cntFree()) reserve(2); +SHOW_EXPR("reserve") SHOW_EXPR(watch(pool).size()) SHOW_EXPR(watch(pool).cntFree()) SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) claim(3); +SHOW_EXPR("claim") SHOW_EXPR(watch(pool).size()) SHOW_EXPR(watch(pool).cntFree()) SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) SHOW_EXPR(show(usedBuff)); free(3); +SHOW_EXPR("free") SHOW_EXPR(watch(pool).size()) SHOW_EXPR(watch(pool).cntFree()) SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) SHOW_EXPR(show(usedBuff)); + +SHOW_EXPR(pool.shouldCleanup()) - pool.yield (3, SIZ, pushMem); + uint removed = pool.cleanup(0.5, pushMem); +SHOW_EXPR(removed) SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(globalPool)); + + claim(1); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + free(1); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + +SHOW_EXPR(pool.shouldCleanup()) + + claim(1); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + free(1); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + +SHOW_EXPR(pool.shouldCleanup()) + + removed = pool.cleanup(0.5, pushMem); +SHOW_EXPR(removed) + +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(globalPool)); + + supply(4); +SHOW_EXPR("supply") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(globalPool)); + + claim(3); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + free(2); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + +SHOW_EXPR(pool.shouldCleanup()) + + claim(2); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + supply(4); +SHOW_EXPR("supply") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(globalPool)); + + free(2); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(usedBuff)); + + claim(1); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + free(1); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(usedBuff)); + +SHOW_EXPR(pool.shouldCleanup()) + removed = pool.cleanup(0.5, pushMem); +SHOW_EXPR(removed) + +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) +SHOW_EXPR(show(globalPool)); + + claim(1); + +SHOW_EXPR("claim") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).cntResd()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + + free(2); + +SHOW_EXPR("free") +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).cntFree()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) + +SHOW_EXPR(pool.shouldCleanup()) + removed = pool.cleanup(0.5, pushMem); +SHOW_EXPR(removed) + +SHOW_EXPR(watch(pool).size()) +SHOW_EXPR(watch(pool).getMaxScore()) +SHOW_EXPR(watch(pool).getTurnover()) SHOW_EXPR(show(globalPool)); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index e5972ab29..0010aed4f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -145434,8 +145434,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + @@ -145469,7 +145469,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -146874,14 +146874,33 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - - - + + + + + + + + + + + + + + + + + + + + + + @@ -147007,8 +147026,20 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + + + + -