diff --git a/include/ircd/db/prefetcher.h b/include/ircd/db/prefetcher.h index 188bc9179..e9e4d12c0 100644 --- a/include/ircd/db/prefetcher.h +++ b/include/ircd/db/prefetcher.h @@ -18,25 +18,15 @@ namespace ircd::db struct ircd::db::prefetcher { + struct ticker; struct request; using closure = std::function; ctx::dock dock; std::deque queue; + std::unique_ptr ticker; ctx::context context; - size_t cache_hits {0}; size_t request_workers {0}; - size_t request_counter {0}; - size_t directs_counter {0}; - size_t handles_counter {0}; - size_t handled_counter {0}; - size_t fetches_counter {0}; - size_t fetched_counter {0}; - size_t cancels_counter {0}; - size_t fetched_bytes_key {0}; - size_t fetched_bytes_val {0}; - microseconds total_snd_req {0us}; - microseconds total_req_fin {0us}; size_t wait_pending(); void request_handle(request &); @@ -77,3 +67,29 @@ static_assert sizeof(ircd::db::prefetcher::request) == 256, "struct ircd::db::prefetcher::request fell out of alignment" ); + +struct ircd::db::prefetcher::ticker +{ + // montonic event counts + size_t queries {0}; ///< All incoming user requests + size_t rejects {0}; ///< Queries which were ignored; already cached + size_t request {0}; ///< Prefetcher requests added to the queue + size_t directs {0}; ///< Direct dispatches to db::request pool + size_t handles {0}; ///< Incremented before dispatch to db::request + size_t handled {0}; ///< Incremented after dispatch to db::request + size_t fetches {0}; ///< Incremented before actual database operation + size_t fetched {0}; ///< Incremented after actual database operation + size_t cancels {0}; ///< Count of canceled operations + + // throughput totals + size_t fetched_bytes_key {0}; ///< Total bytes of key data received + size_t fetched_bytes_val {0}; ///< Total bytes of value data received + + // from last operation only + microseconds last_snd_req {0us}; ///< duration request was queued here + microseconds last_req_fin {0us}; ///< duration for database operation + + // accumulated latency totals + microseconds accum_snd_req {0us}; + microseconds accum_req_fin {0us}; +}; diff --git a/ircd/db.cc b/ircd/db.cc index 930e6f5e8..896d391ef 100644 --- a/ircd/db.cc +++ b/ircd/db.cc @@ -3820,7 +3820,11 @@ ircd::db::prefetcher; // db::prefetcher // ircd::db::prefetcher::prefetcher() -:context +:ticker +{ + std::make_unique() +} +,context { "db.prefetcher", 128_KiB, @@ -3860,15 +3864,17 @@ ircd::db::prefetcher::operator()(column &c, static_cast(c) }; + assert(ticker); + ticker->queries++; if(db::cached(c, key, opts)) { - ++cache_hits; + ticker->rejects++; return false; } queue.emplace_back(d, c, key); queue.back().snd = now(); - ++request_counter; + ticker->request++; // Branch here based on whether it's not possible to directly dispatch // a db::request worker. If all request workers are busy we notify our own @@ -3891,7 +3897,7 @@ ircd::db::prefetcher::operator()(column &c, } const ctx::critical_assertion ca; - ++directs_counter; + ticker->directs++; this->handle(); return true; } @@ -3942,6 +3948,8 @@ ircd::db::prefetcher::cancel(const closure &closure) if(canceled) dock.notify_all(); + assert(ticker); + ticker->cancels += canceled; return canceled; } @@ -3956,7 +3964,8 @@ try if(queue.empty()) return false; - if(request_counter <= handles_counter) + assert(ticker); + if(ticker->request <= ticker->handles) return false; return true; @@ -3982,9 +3991,9 @@ ircd::db::prefetcher::handle() std::bind(&prefetcher::request_worker, this) }; - ++handles_counter; + ticker->handles++; db::request(std::move(handler)); - ++handled_counter; + ticker->handled++; } void @@ -4027,24 +4036,27 @@ ircd::db::prefetcher::request_worker() if(request == end(queue)) return; - request->req = now(); + assert(ticker); assert(request->fin == steady_point::min()); - total_snd_req += duration_cast(request->req - request->snd); - ++fetches_counter; + request->req = now(); + ticker->last_snd_req = duration_cast(request->req - request->snd); + ticker->accum_snd_req += ticker->last_snd_req; + + ticker->fetches++; request_handle(*request); assert(request->fin != steady_point::min()); - ++fetched_counter; + ticker->fetched++; #ifdef IRCD_DB_DEBUG_PREFETCH log::debug { - log, "prefetcher ch:%zu rc:%zu hc:%zu fc:%zu dc:%zu cc:%zu queue:%zu rw:%zu", - cache_hits, - request_counter, - handles_counter, - fetches_counter, - directs_counter, - cancels_counter, + log, "prefetcher reject:%zu request:%zu handle:%zu fetch:%zu direct:%zu cancel:%zu queue:%zu rw:%zu", + ticker->rejects, + ticker->request, + ticker->handles, + ticker->fetches, + ticker->directs, + ticker->cancels, queue.size(), this->request_workers, }; @@ -4085,7 +4097,8 @@ try const ctx::critical_assertion ca; request.fin = now(); - total_req_fin += duration_cast(request.fin - request.req); + ticker->last_req_fin = duration_cast(request.fin - request.req); + ticker->accum_req_fin += ticker->last_req_fin; const bool lte { valid_lte(*it, key) @@ -4093,8 +4106,8 @@ try if(likely(lte)) { - fetched_bytes_key += size(it->key()); - fetched_bytes_val += size(it->value()); + ticker->fetched_bytes_key += size(it->key()); + ticker->fetched_bytes_val += size(it->value()); } #ifdef IRCD_DB_DEBUG_PREFETCH @@ -4139,7 +4152,7 @@ ircd::db::prefetcher::wait_pending() { const size_t fetched_counter { - this->fetched_counter + ticker->fetched }; const size_t fetched_target @@ -4149,7 +4162,7 @@ ircd::db::prefetcher::wait_pending() dock.wait([this, &fetched_target] { - return this->fetched_counter >= fetched_target; + return this->ticker->fetched >= fetched_target; }); assert(fetched_target >= fetched_counter);