void DRAMSimMemory::initStats(AggregateStat* parentStat) { AggregateStat* memStats = new AggregateStat(); memStats->init(name.c_str(), "Memory controller stats"); profReads.init("rd", "Read requests"); memStats->append(&profReads); profWrites.init("wr", "Write requests"); memStats->append(&profWrites); profTotalRdLat.init("rdlat", "Total latency experienced by read requests"); memStats->append(&profTotalRdLat); profTotalWrLat.init("wrlat", "Total latency experienced by write requests"); memStats->append(&profTotalWrLat); parentStat->append(memStats); }
void ZArray::initStats(AggregateStat* parentStat) { AggregateStat* objStats = new AggregateStat(); objStats->init("array", "ZArray stats"); statSwaps.init("swaps", "Block swaps in replacement process"); objStats->append(&statSwaps); parentStat->append(objStats); }
void TimingCache::initStats(AggregateStat* parentStat) { AggregateStat* cacheStat = new AggregateStat(); cacheStat->init(name.c_str(), "Timing cache stats"); initCacheStats(cacheStat); //Stats specific to timing cache profOccHist.init("occHist", "Occupancy MSHR cycle histogram", numMSHRs+1); cacheStat->append(&profOccHist); profHitLat.init("latHit", "Cumulative latency accesses that hit (demand and non-demand)"); profMissRespLat.init("latMissResp", "Cumulative latency for miss start to response"); profMissLat.init("latMiss", "Cumulative latency for miss start to finish (free MSHR)"); cacheStat->append(&profHitLat); cacheStat->append(&profMissRespLat); cacheStat->append(&profMissLat); parentStat->append(cacheStat); }
void DDRMemory::initStats(AggregateStat* parentStat) { AggregateStat* memStats = new AggregateStat(); memStats->init(name.c_str(), "Memory controller stats"); profReads.init("rd", "Read requests"); memStats->append(&profReads); profWrites.init("wr", "Write requests"); memStats->append(&profWrites); profTotalRdLat.init("rdlat", "Total latency experienced by read requests"); memStats->append(&profTotalRdLat); profTotalWrLat.init("wrlat", "Total latency experienced by write requests"); memStats->append(&profTotalWrLat); profReadHits.init("rdhits", "Read row hits"); memStats->append(&profReadHits); profWriteHits.init("wrhits", "Write row hits"); memStats->append(&profWriteHits); latencyHist.init("mlh", "latency histogram for memory requests", NUMBINS); memStats->append(&latencyHist); parentStat->append(memStats); }
void NVMainMemory::initStats(AggregateStat* parentStat) { AggregateStat* memStats = new AggregateStat(); memStats->init(name.c_str(), "Memory controller stats"); profIssued.init("issued", "Issued requests"); memStats->append(&profIssued); profReads.init("rd", "Read requests"); memStats->append(&profReads); profWrites.init("wr", "Write requests"); memStats->append(&profWrites); profPUTS.init("PUTS", "Clean Evictions (from lower level)"); memStats->append(&profPUTS); profPUTX.init("PUTX", "Dirty Evictions (from lower level)"); memStats->append(&profPUTX); profTotalRdLat.init("rdlat", "Total latency experienced by read requests"); memStats->append(&profTotalRdLat); profTotalWrLat.init("wrlat", "Total latency experienced by write requests"); memStats->append(&profTotalWrLat); profMemoryFootprint.init("footprint", "Total memory footprint in bytes"); memStats->append(&profMemoryFootprint); profMemoryAddresses.init("addresses", "Total number of distinct memory addresses"); memStats->append(&profMemoryAddresses); latencyHist.init("mlh", "latency histogram for memory requests", NUMBINS); memStats->append(&latencyHist); addressReuseHist.init("addressReuse", "address reuse histogram for memory requests", NUMBINS); memStats->append(&addressReuseHist); parentStat->append(memStats); }
ProcStats::ProcStats(AggregateStat* parentStat, AggregateStat* _coreStats) : coreStats(_coreStats) { uint32_t maxProcs = zinfo->lineSize; lastUpdatePhase = 0; // Check that coreStats are appropriate assert(coreStats); for (uint32_t i = 0; i < coreStats->size(); i++) { Stat* s = coreStats->get(i); AggregateStat* as = dynamic_cast<AggregateStat*>(s); auto err = [s](const char* reason) { panic("Stat %s is not per-core (%s)", s->name(), reason); }; if (!as) err("not aggregate stat"); if (!as->isRegular()) err("irregular aggregate"); if (as->size() != zinfo->numCores) err("elems != cores"); } // Initialize all the buffers bufSize = StatSize(coreStats); buf = gm_calloc<uint64_t>(bufSize); lastBuf = gm_calloc<uint64_t>(bufSize); // Create the procStats procStats = new AggregateStat(true); procStats->init("procStats", "Per-process stats"); for (uint32_t p = 0; p < maxProcs; p++) { AggregateStat* ps = new AggregateStat(false); const char* name = gm_strdup(("procStats-" + Str(p)).c_str()); ps->init(name, "Per-process stats"); for (uint32_t i = 0; i < coreStats->size(); i++) { AggregateStat* as = dynamic_cast<AggregateStat*>(coreStats->get(i)); assert(as && as->isRegular()); ps->append(replStat(as->get(0), as->name(), as->desc())); } procStats->append(ps); } parentStat->append(procStats); }
AggregateStat* FilterStatsLevel(const AggregateStat* src, const regex& filter, const char* prefix) { string base = prefix? (string(prefix) + src->name() + ".") : ""; //if NULL prefix, omit our name (we're root) vector<Stat*> children; for (uint32_t i = 0; i < src->size(); i++) { Stat* child = src->get(i); if (AggregateStat* as = dynamic_cast<AggregateStat*>(child)) { AggregateStat* fs = FilterStatsLevel(as, filter, base.c_str()); if (fs) children.push_back(fs); } else { string name = base + child->name(); if (regex_match(name, filter)) children.push_back(child); } } if (children.size()) { AggregateStat* res = new AggregateStat(src->isRegular()); res->init(src->name(), src->desc()); for (Stat* c : children) res->append(c); return res; } else { return NULL; } }
Stat* ProcStats::replStat(Stat* s, const char* name, const char* desc) { if (!name) name = s->name(); if (!desc) desc = s->desc(); if (AggregateStat* as = dynamic_cast<AggregateStat*>(s)) { AggregateStat* res = new AggregateStat(as->isRegular()); res->init(name, desc); for (uint32_t i = 0; i < as->size(); i++) { res->append(replStat(as->get(i))); } return res; } else if (dynamic_cast<ScalarStat*>(s)) { Counter* res = new ProcessCounter(this); res->init(name, desc); return res; } else if (VectorStat* vs = dynamic_cast<VectorStat*>(s)) { VectorCounter* res = new ProcessVectorCounter(this); assert(!vs->hasCounterNames()); // FIXME: Implement counter name copying res->init(name, desc, vs->size()); return res; } else { panic("Unrecognized stat type"); return nullptr; } }