summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/blk.hh12
-rw-r--r--src/mem/cache/cache_impl.hh6
-rw-r--r--src/mem/cache/prefetch/base.cc1
-rw-r--r--src/mem/cache/tags/base.cc23
-rw-r--r--src/mem/cache/tags/base.hh22
-rw-r--r--src/mem/cache/tags/lru.cc40
-rw-r--r--src/mem/cache/tags/lru.hh5
7 files changed, 107 insertions, 2 deletions
diff --git a/src/mem/cache/blk.hh b/src/mem/cache/blk.hh
index 4a89f3892..47cd305c0 100644
--- a/src/mem/cache/blk.hh
+++ b/src/mem/cache/blk.hh
@@ -80,6 +80,9 @@ enum CacheBlkStatusBits {
class CacheBlk
{
public:
+ /** Task Id associated with this block */
+ uint32_t task_id;
+
/** The address space ID of this block. */
int asid;
/** Data block tag value. */
@@ -119,6 +122,8 @@ class CacheBlk
/** holds the source requestor ID for this block. */
int srcMasterId;
+ Tick tickInserted;
+
protected:
/**
* Represents that the indicated thread context has a "lock" on
@@ -162,9 +167,11 @@ class CacheBlk
public:
CacheBlk()
- : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0),
+ : task_id(ContextSwitchTaskId::Unknown),
+ asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0),
set(-1), isTouched(false), refCount(0),
- srcMasterId(Request::invldMasterId)
+ srcMasterId(Request::invldMasterId),
+ tickInserted(0)
{}
/**
@@ -182,6 +189,7 @@ class CacheBlk
whenReady = rhs.whenReady;
set = rhs.set;
refCount = rhs.refCount;
+ task_id = rhs.task_id;
return *this;
}
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 6d7011819..e86b3d704 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -1074,6 +1074,11 @@ Cache<TagStore>::writebackBlk(BlkType *blk)
Request *writebackReq =
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0,
Request::wbMasterId);
+
+ writebackReq->taskId(blk->task_id);
+ blk->task_id= ContextSwitchTaskId::Unknown;
+ blk->tickInserted = curTick();
+
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback);
if (blk->isWritable()) {
writeback->setSupplyExclusive();
@@ -1120,6 +1125,7 @@ Cache<TagStore>::writebackVisitor(BlkType &blk)
Request request(tags->regenerateBlkAddr(blk.tag, blk.set),
blkSize, 0, Request::funcMasterId);
+ request.taskId(blk.task_id);
Packet packet(&request, MemCmd::WriteReq);
packet.dataStatic(blk.data);
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 6463f78f8..ed7b63f82 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -247,6 +247,7 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick tick)
// create a prefetch memreq
Request *prefetchReq = new Request(*addrIter, blkSize, 0, masterId);
+ prefetchReq->taskId(ContextSwitchTaskId::Prefetcher);
PacketPtr prefetch =
new Packet(prefetchReq, MemCmd::HardPFReq);
prefetch->allocate();
diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc
index 947bd05de..b669a5b06 100644
--- a/src/mem/cache/tags/base.cc
+++ b/src/mem/cache/tags/base.cc
@@ -125,5 +125,28 @@ BaseTags::regStats()
avgOccs = occupancies / Stats::constant(numBlocks);
+ occupanciesTaskId
+ .init(ContextSwitchTaskId::NumTaskId)
+ .name(name() + ".occ_task_id_blocks")
+ .desc("Occupied blocks per task id")
+ .flags(nozero | nonan)
+ ;
+
+ ageTaskId
+ .init(ContextSwitchTaskId::NumTaskId, 5)
+ .name(name() + ".age_task_id_blocks")
+ .desc("Occupied blocks per task id")
+ .flags(nozero | nonan)
+ ;
+
+ percentOccsTaskId
+ .name(name() + ".occ_task_id_percent")
+ .desc("Percentage of cache occupancy per task id")
+ .flags(nozero)
+ ;
+
+ percentOccsTaskId = occupanciesTaskId / Stats::constant(numBlocks);
+
+ registerDumpCallback(new BaseTagsDumpCallback(this));
registerExitCallback(new BaseTagsCallback(this));
}
diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh
index 8ce7d972a..e8c71f01f 100644
--- a/src/mem/cache/tags/base.hh
+++ b/src/mem/cache/tags/base.hh
@@ -121,6 +121,15 @@ class BaseTags : public ClockedObject
/** Average occ % of each requestor using the cache */
Stats::Formula avgOccs;
+ /** Occupancy of each context/cpu using the cache */
+ Stats::Vector occupanciesTaskId;
+
+ /** Occupancy of each context/cpu using the cache */
+ Stats::Vector2d ageTaskId;
+
+ /** Occ % of each context/cpu using the cache */
+ Stats::Formula percentOccsTaskId;
+
/**
* @}
*/
@@ -152,6 +161,11 @@ class BaseTags : public ClockedObject
virtual void cleanupRefs() {}
/**
+ * Computes stats just prior to dump event
+ */
+ virtual void computeStats() {}
+
+ /**
*iterated through all blocks and clear all locks
*Needed to clear all lock tracking at once
*/
@@ -171,4 +185,12 @@ class BaseTagsCallback : public Callback
virtual void process() { tags->cleanupRefs(); };
};
+class BaseTagsDumpCallback : public Callback
+{
+ BaseTags *tags;
+ public:
+ BaseTagsDumpCallback(BaseTags *t) : tags(t) {}
+ virtual void process() { tags->computeStats(); };
+};
+
#endif //__BASE_TAGS_HH__
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index db0cc0839..6b05744af 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -176,6 +176,7 @@ LRU::insertBlock(PacketPtr pkt, BlkType *blk)
{
Addr addr = pkt->getAddr();
MasterID master_id = pkt->req->masterId();
+ uint32_t task_id = pkt->req->taskId();
if (!blk->isTouched) {
tagsInUse++;
blk->isTouched = true;
@@ -210,6 +211,8 @@ LRU::insertBlock(PacketPtr pkt, BlkType *blk)
assert(master_id < cache->system->maxMasters());
occupancies[master_id]++;
blk->srcMasterId = master_id;
+ blk->task_id = task_id;
+ blk->tickInserted = curTick();
unsigned set = extractSet(addr);
sets[set].moveToHead(blk);
@@ -224,6 +227,8 @@ LRU::invalidate(BlkType *blk)
assert(blk->srcMasterId < cache->system->maxMasters());
occupancies[blk->srcMasterId]--;
blk->srcMasterId = Request::invldMasterId;
+ blk->task_id = ContextSwitchTaskId::Unknown;
+ blk->tickInserted = curTick();
// should be evicted before valid blocks
unsigned set = blk->set;
@@ -270,3 +275,38 @@ LRU::cleanupRefs()
}
}
}
+
+void
+LRU::computeStats()
+{
+ for (unsigned i = 0; i < ContextSwitchTaskId::NumTaskId; ++i) {
+ occupanciesTaskId[i] = 0;
+ for (unsigned j = 0; j < 5; ++j) {
+ ageTaskId[i][j] = 0;
+ }
+ }
+
+ for (unsigned i = 0; i < numSets * assoc; ++i) {
+ if (blks[i].isValid()) {
+ assert(blks[i].task_id < ContextSwitchTaskId::NumTaskId);
+ occupanciesTaskId[blks[i].task_id]++;
+ Tick age = curTick() - blks[i].tickInserted;
+ assert(age >= 0);
+
+ int age_index;
+ if (age / SimClock::Int::us < 10) { // <10us
+ age_index = 0;
+ } else if (age / SimClock::Int::us < 100) { // <100us
+ age_index = 1;
+ } else if (age / SimClock::Int::ms < 1) { // <1ms
+ age_index = 2;
+ } else if (age / SimClock::Int::ms < 10) { // <10ms
+ age_index = 3;
+ } else
+ age_index = 4; // >10ms
+
+ ageTaskId[blks[i].task_id][age_index]++;
+ }
+ }
+}
+
diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh
index af7f8665d..68c29b754 100644
--- a/src/mem/cache/tags/lru.hh
+++ b/src/mem/cache/tags/lru.hh
@@ -253,6 +253,11 @@ public:
virtual std::string print() const;
/**
+ * Called prior to dumping stats to compute task occupancy
+ */
+ virtual void computeStats();
+
+ /**
* Visit each block in the tag store and apply a visitor to the
* block.
*