diff --git a/src/dev/arm/smmu_v3_caches.cc b/src/dev/arm/smmu_v3_caches.cc index 59f5acad03..b09fb31e72 100644 --- a/src/dev/arm/smmu_v3_caches.cc +++ b/src/dev/arm/smmu_v3_caches.cc @@ -1228,68 +1228,105 @@ WalkCache::pickEntryIdxToReplace(const Set &set, WalkCache:: WalkCacheStats::WalkCacheStats(Stats::Group *parent) - : Stats::Group(parent) + : Stats::Group(parent), + ADD_STAT(totalLookupsByStageLevel, UNIT_COUNT, + "Total number of lookups"), + ADD_STAT(totalMissesByStageLevel, UNIT_COUNT, + "Total number of misses"), + ADD_STAT(totalUpdatesByStageLevel, UNIT_COUNT, + "Total number of updates"), + ADD_STAT(insertionsByStageLevel, UNIT_COUNT, + "Number of insertions (not replacements)") { using namespace Stats; + totalLookupsByStageLevel + .init(2, WALK_CACHE_LEVELS) + .flags(pdf); + totalMissesByStageLevel + .init(2, WALK_CACHE_LEVELS) + .flags(pdf); + totalUpdatesByStageLevel + .init(2, WALK_CACHE_LEVELS) + .flags(pdf); + insertionsByStageLevel + .init(2, WALK_CACHE_LEVELS) + .flags(pdf); + for (int s = 0; s < 2; s++) { + totalLookupsByStageLevel.subname(s, csprintf("S%d", s + 1)); + totalMissesByStageLevel.subname(s, csprintf("S%d", s + 1)); + totalUpdatesByStageLevel.subname(s, csprintf("S%d", s + 1)); + insertionsByStageLevel.subname(s, csprintf("S%d", s + 1)); + for (int l = 0; l < WALK_CACHE_LEVELS; l++) { - averageLookupsByStageLevel[s][l] - .name(csprintf("averageLookupsS%dL%d", s+1, l)) - .desc("Average number lookups per second") - .flags(pdf); + totalLookupsByStageLevel.ysubname(l, csprintf("L%d", l)); + totalMissesByStageLevel.ysubname(l, csprintf("L%d", l)); + totalUpdatesByStageLevel.ysubname(l, csprintf("L%d", l)); + insertionsByStageLevel.ysubname(l, csprintf("L%d", l)); - totalLookupsByStageLevel[s][l] - .name(csprintf("totalLookupsS%dL%d", s+1, l)) - .desc("Total number of lookups") - .flags(pdf); + auto avg_lookup = new Stats::Formula( + this, + csprintf("averageLookups_S%dL%d", s+1, l).c_str(), + UNIT_RATE(Stats::Units::Count, Stats::Units::Second), + "Average number lookups per second"); + avg_lookup->flags(pdf); + averageLookupsByStageLevel.push_back(avg_lookup); - averageLookupsByStageLevel[s][l] = + *avg_lookup = totalLookupsByStageLevel[s][l] / simSeconds; + auto avg_misses = new Stats::Formula( + this, + csprintf("averageMisses_S%dL%d", s+1, l).c_str(), + UNIT_RATE(Stats::Units::Count, Stats::Units::Second), + "Average number misses per second"); + avg_misses->flags(pdf); + averageMissesByStageLevel.push_back(avg_misses); - averageMissesByStageLevel[s][l] - .name(csprintf("averageMissesS%dL%d", s+1, l)) - .desc("Average number misses per second") - .flags(pdf); - - totalMissesByStageLevel[s][l] - .name(csprintf("totalMissesS%dL%d", s+1, l)) - .desc("Total number of misses") - .flags(pdf); - - averageMissesByStageLevel[s][l] = + *avg_misses = totalMissesByStageLevel[s][l] / simSeconds; + auto avg_updates = new Stats::Formula( + this, + csprintf("averageUpdates_S%dL%d", s+1, l).c_str(), + UNIT_RATE(Stats::Units::Count, Stats::Units::Second), + "Average number updates per second"); + avg_updates->flags(pdf); + averageUpdatesByStageLevel.push_back(avg_updates); - averageUpdatesByStageLevel[s][l] - .name(csprintf("averageUpdatesS%dL%d", s+1, l)) - .desc("Average number updates per second") - .flags(pdf); - - totalUpdatesByStageLevel[s][l] - .name(csprintf("totalUpdatesS%dL%d", s+1, l)) - .desc("Total number of updates") - .flags(pdf); - - averageUpdatesByStageLevel[s][l] = + *avg_updates = totalUpdatesByStageLevel[s][l] / simSeconds; + auto avg_hitrate = new Stats::Formula( + this, + csprintf("averageHitRate_S%dL%d", s+1, l).c_str(), + UNIT_RATIO, + "Average hit rate"); + avg_hitrate->flags(pdf); + averageHitRateByStageLevel.push_back(avg_hitrate); - averageHitRateByStageLevel[s][l] - .name(csprintf("averageHitRateS%dL%d", s+1, l)) - .desc("Average hit rate") - .flags(pdf); - - averageHitRateByStageLevel[s][l] = + *avg_hitrate = (totalLookupsByStageLevel[s][l] - totalMissesByStageLevel[s][l]) / totalLookupsByStageLevel[s][l]; - insertionsByStageLevel[s][l] - .name(csprintf("insertionsS%dL%d", s+1, l)) - .desc("Number of insertions (not replacements)") - .flags(pdf); } } } + +WalkCache:: +WalkCacheStats::~WalkCacheStats() +{ + for (auto avg_lookup : averageLookupsByStageLevel) + delete avg_lookup; + + for (auto avg_miss : averageMissesByStageLevel) + delete avg_miss; + + for (auto avg_update : averageUpdatesByStageLevel) + delete avg_update; + + for (auto avg_hitrate : averageHitRateByStageLevel) + delete avg_hitrate; +} diff --git a/src/dev/arm/smmu_v3_caches.hh b/src/dev/arm/smmu_v3_caches.hh index dee09f2314..07c6242d75 100644 --- a/src/dev/arm/smmu_v3_caches.hh +++ b/src/dev/arm/smmu_v3_caches.hh @@ -325,22 +325,23 @@ class WalkCache : public SMMUv3BaseCache struct WalkCacheStats : public Stats::Group { WalkCacheStats(Stats::Group *parent); + ~WalkCacheStats(); unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS]; + std::vector averageLookupsByStageLevel; + Stats::Vector2d totalLookupsByStageLevel; unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS]; + std::vector averageMissesByStageLevel; + Stats::Vector2d totalMissesByStageLevel; unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS]; - Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS]; + std::vector averageUpdatesByStageLevel; + Stats::Vector2d totalUpdatesByStageLevel; - Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS]; + std::vector averageHitRateByStageLevel; - Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS]; + Stats::Vector2d insertionsByStageLevel; } walkCacheStats; private: typedef std::vector Set;