}
void
-BeesHashTable::prefetch_loop()
+BeesHashTable::print_occupancy(ostream &os)
{
- Uname uname;
- while (!m_stop_requested) {
- size_t width = 64;
- vector<size_t> occupancy(width, 0);
- size_t occupied_count = 0;
- const size_t total_count = m_cells;
-
- // Sum the per-extent occupancy fragments maintained at load and
- // writeback — no cell walk. Each extent contributes its cached
- // bucket-fill histogram. The old type breakdowns (compressed,
- // unaligned_eof, toxic) are gone: those were v1 BeesAddress bits
- // that scan-next neither sets on store nor reads on fetch.
- for (uint64_t ext = 0; ext < m_extents && !m_stop_requested; ++ext) {
- catch_all([&]() {
- BEESNOTE("summarizing hash table extent #" << ext << " of " << m_extents);
- auto lock = lock_extent_by_index(ext);
- const auto &hist = m_extent_metadata.at(ext).m_fill_histogram;
- for (size_t fill = 0; fill < hist.size(); ++fill) {
- const size_t buckets_at_fill = hist[fill];
- occupancy.at(fill * width / (1 + c_cells_per_bucket)) += buckets_at_fill;
- occupied_count += fill * buckets_at_fill;
- }
- });
- }
-
- BEESNOTE("calculating hash table statistics");
-
- vector<string> histogram;
- vector<size_t> thresholds;
- size_t threshold = 1;
- bool threshold_exceeded = false;
- do {
- threshold_exceeded = false;
- histogram.push_back(string(width, ' '));
- thresholds.push_back(threshold);
- for (size_t x = 0; x < width; ++x) {
- if (occupancy.at(x) >= threshold) {
- histogram.back().at(x) = '#';
- threshold_exceeded = true;
- }
+ const size_t width = 64;
+ vector<size_t> occupancy(width, 0);
+ size_t occupied_count = 0;
+ const size_t total_count = m_cells;
+
+ // Sum the per-extent occupancy fragments maintained at load and
+ // writeback — no cell walk. Each extent contributes its cached
+ // bucket-fill histogram. The old type breakdowns (compressed,
+ // unaligned_eof, toxic) are gone: those were v1 BeesAddress bits that
+ // scan-next neither sets on store nor reads on fetch.
+ for (uint64_t ext = 0; ext < m_extents; ++ext) {
+ catch_all([&]() {
+ BEESNOTE("summarizing hash table extent #" << ext << " of " << m_extents);
+ auto lock = lock_extent_by_index(ext);
+ const auto &hist = m_extent_metadata.at(ext).m_fill_histogram;
+ for (size_t fill = 0; fill < hist.size(); ++fill) {
+ const size_t buckets_at_fill = hist[fill];
+ occupancy.at(fill * width / (1 + c_cells_per_bucket)) += buckets_at_fill;
+ occupied_count += fill * buckets_at_fill;
}
- threshold *= 2;
- } while (threshold_exceeded);
-
- ostringstream out;
- size_t count = histogram.size();
- bool first_line = true;
- for (auto it = histogram.rbegin(); it != histogram.rend(); ++it) {
- out << *it << " " << thresholds.at(--count);
- if (first_line) {
- first_line = false;
- out << " pages";
+ });
+ }
+
+ BEESNOTE("calculating hash table statistics");
+
+ vector<string> histogram;
+ vector<size_t> thresholds;
+ size_t threshold = 1;
+ bool threshold_exceeded = false;
+ do {
+ threshold_exceeded = false;
+ histogram.push_back(string(width, ' '));
+ thresholds.push_back(threshold);
+ for (size_t x = 0; x < width; ++x) {
+ if (occupancy.at(x) >= threshold) {
+ histogram.back().at(x) = '#';
+ threshold_exceeded = true;
}
- out << "\n";
}
+ threshold *= 2;
+ } while (threshold_exceeded);
+
+ ostringstream out;
+ size_t count = histogram.size();
+ bool first_line = true;
+ for (auto it = histogram.rbegin(); it != histogram.rend(); ++it) {
+ out << *it << " " << thresholds.at(--count);
+ if (first_line) {
+ first_line = false;
+ out << " pages";
+ }
+ out << "\n";
+ }
+ os << "Hash table page occupancy histogram (" << occupied_count << "/" << total_count << " cells occupied, " << (occupied_count * 100 / total_count) << "%)\n"
+ << out.str() << "0% | 25% | 50% | 75% | 100% page fill";
+}
+
+void
+BeesHashTable::prefetch_loop()
+{
+ Uname uname;
+ while (!m_stop_requested) {
ostringstream graph_blob;
graph_blob << "Now: " << format_time(time(NULL)) << "\n";
graph_blob << "Version: " << BEES_VERSION << "\n";
graph_blob << "Kernel: " << uname.sysname << " " << uname.release << " " << uname.machine << " " << uname.version << "\n";
- graph_blob
- << "\nHash table page occupancy histogram (" << occupied_count << "/" << total_count << " cells occupied, " << (occupied_count * 100 / total_count) << "%)\n"
- << out.str() << "0% | 25% | 50% | 75% | 100% page fill";
-
+ graph_blob << "\n";
+ print_occupancy(graph_blob);
graph_blob << "\n\n";
graph_blob << "TOTAL:\n";