|
21 | 21 | #include "cachelib/common/PercentileStats.h" |
22 | 22 |
|
23 | 23 | DECLARE_bool(report_api_latency); |
| 24 | +DECLARE_string(report_ac_memory_usage_stats); |
24 | 25 |
|
25 | 26 | namespace facebook { |
26 | 27 | namespace cachelib { |
@@ -100,6 +101,8 @@ struct Stats { |
100 | 101 | uint64_t invalidDestructorCount{0}; |
101 | 102 | int64_t unDestructedItemCount{0}; |
102 | 103 |
|
| 104 | + std::map<PoolId, std::map<ClassId, ACStats>> allocationClassStats; |
| 105 | + |
103 | 106 | // populate the counters related to nvm usage. Cache implementation can decide |
104 | 107 | // what to populate since not all of those are interesting when running |
105 | 108 | // cachebench. |
@@ -131,6 +134,61 @@ struct Stats { |
131 | 134 | << std::endl; |
132 | 135 | } |
133 | 136 |
|
| 137 | + if (FLAGS_report_ac_memory_usage_stats != "") { |
| 138 | + auto formatMemory = [&](size_t bytes) -> std::tuple<std::string, double> { |
| 139 | + if (FLAGS_report_ac_memory_usage_stats == "raw") { |
| 140 | + return {"B", bytes}; |
| 141 | + } |
| 142 | + |
| 143 | + constexpr double KB = 1024.0; |
| 144 | + constexpr double MB = 1024.0 * 1024; |
| 145 | + constexpr double GB = 1024.0 * 1024 * 1024; |
| 146 | + |
| 147 | + if (bytes >= GB) { |
| 148 | + return {"GB", static_cast<double>(bytes) / GB}; |
| 149 | + } else if (bytes >= MB) { |
| 150 | + return {"MB", static_cast<double>(bytes) / MB}; |
| 151 | + } else if (bytes >= KB) { |
| 152 | + return {"KB", static_cast<double>(bytes) / KB}; |
| 153 | + } else { |
| 154 | + return {"B", bytes}; |
| 155 | + } |
| 156 | + }; |
| 157 | + |
| 158 | + auto foreachAC = [&](auto cb) { |
| 159 | + for (auto& pidStat : allocationClassStats) { |
| 160 | + for (auto& cidStat : pidStat.second) { |
| 161 | + cb(pidStat.first, cidStat.first, cidStat.second); |
| 162 | + } |
| 163 | + } |
| 164 | + }; |
| 165 | + |
| 166 | + foreachAC([&](auto pid, auto cid, auto stats) { |
| 167 | + auto [allocSizeSuffix, allocSize] = formatMemory(stats.allocSize); |
| 168 | + auto [memorySizeSuffix, memorySize] = |
| 169 | + formatMemory(stats.totalAllocatedSize()); |
| 170 | + out << folly::sformat("pid{:2} cid{:4} {:8.2f}{} memorySize: {:8.2f}{}", |
| 171 | + pid, cid, allocSize, allocSizeSuffix, memorySize, |
| 172 | + memorySizeSuffix) |
| 173 | + << std::endl; |
| 174 | + }); |
| 175 | + |
| 176 | + foreachAC([&](auto pid, auto cid, auto stats) { |
| 177 | + auto [allocSizeSuffix, allocSize] = formatMemory(stats.allocSize); |
| 178 | + |
| 179 | + // If the pool is not full, extrapolate usageFraction for AC assuming it |
| 180 | + // will grow at the same rate. This value will be the same for all ACs. |
| 181 | + auto acUsageFraction = (poolUsageFraction[pid] < 1.0) |
| 182 | + ? poolUsageFraction[pid] |
| 183 | + : stats.usageFraction(); |
| 184 | + |
| 185 | + out << folly::sformat( |
| 186 | + "pid{:2} cid{:4} {:8.2f}{} usageFraction: {:4.2f}", pid, cid, |
| 187 | + allocSize, allocSizeSuffix, acUsageFraction) |
| 188 | + << std::endl; |
| 189 | + }); |
| 190 | + } |
| 191 | + |
134 | 192 | if (numCacheGets > 0) { |
135 | 193 | out << folly::sformat("Cache Gets : {:,}", numCacheGets) << std::endl; |
136 | 194 | out << folly::sformat("Hit Ratio : {:6.2f}%", overallHitRatio) |
|
0 commit comments