summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/BaseCache.py2
-rw-r--r--src/mem/cache/tags/Tags.py2
-rw-r--r--src/mem/cache/tags/base.cc10
-rw-r--r--src/mem/cache/tags/base.hh5
-rw-r--r--src/mem/cache/tags/lru.cc20
-rw-r--r--src/mem/cache/tags/lru.hh2
6 files changed, 40 insertions, 1 deletions
diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py
index df4602199..9ffe39981 100644
--- a/src/mem/cache/BaseCache.py
+++ b/src/mem/cache/BaseCache.py
@@ -69,4 +69,6 @@ class BaseCache(MemObject):
mem_side = MasterPort("Port on side closer to MEM")
addr_ranges = VectorParam.AddrRange([AllMemory], "The address range for the CPU-side port")
system = Param.System(Parent.any, "System we belong to")
+ sequential_access = Param.Bool(False,
+ "Whether to access tags and data sequentially")
tags = Param.BaseTags(LRU(), "Tag Store for LRU caches")
diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py
index c5beff4a7..7c0dded32 100644
--- a/src/mem/cache/tags/Tags.py
+++ b/src/mem/cache/tags/Tags.py
@@ -58,6 +58,8 @@ class LRU(BaseTags):
cxx_class = 'LRU'
cxx_header = "mem/cache/tags/lru.hh"
assoc = Param.Int(Parent.assoc, "associativity")
+ sequential_access = Param.Bool(Parent.sequential_access,
+ "Whether to access tags and data sequentially")
class FALRU(BaseTags):
type = 'FALRU'
diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc
index b669a5b06..446c1ea49 100644
--- a/src/mem/cache/tags/base.cc
+++ b/src/mem/cache/tags/base.cc
@@ -147,6 +147,16 @@ BaseTags::regStats()
percentOccsTaskId = occupanciesTaskId / Stats::constant(numBlocks);
+ tagAccesses
+ .name(name() + ".tag_accesses")
+ .desc("Number of tag accesses")
+ ;
+
+ dataAccesses
+ .name(name() + ".data_accesses")
+ .desc("Number of data accesses")
+ ;
+
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 e8c71f01f..9e1fb1972 100644
--- a/src/mem/cache/tags/base.hh
+++ b/src/mem/cache/tags/base.hh
@@ -130,6 +130,11 @@ class BaseTags : public ClockedObject
/** Occ % of each context/cpu using the cache */
Stats::Formula percentOccsTaskId;
+ /** Number of tags consulted over all accesses. */
+ Stats::Scalar tagAccesses;
+ /** Number of data blocks consulted over all accesses. */
+ Stats::Scalar dataAccesses;
+
/**
* @}
*/
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index 6b05744af..58f3f0977 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -58,7 +58,8 @@ using namespace std;
LRU::LRU(const Params *p)
:BaseTags(p), assoc(p->assoc),
- numSets(p->size / (p->block_size * p->assoc))
+ numSets(p->size / (p->block_size * p->assoc)),
+ sequentialAccess(p->sequential_access)
{
// Check parameters
if (blkSize < 4 || !isPowerOf2(blkSize)) {
@@ -132,6 +133,19 @@ LRU::accessBlock(Addr addr, Cycles &lat, int master_id)
unsigned set = extractSet(addr);
BlkType *blk = sets[set].findBlk(tag);
lat = hitLatency;
+
+ // Access all tags in parallel, hence one in each way. The data side
+ // either accesses all blocks in parallel, or one block sequentially on
+ // a hit. Sequential access with a miss doesn't access data.
+ tagAccesses += assoc;
+ if (sequentialAccess) {
+ if (blk != NULL) {
+ dataAccesses += 1;
+ }
+ } else {
+ dataAccesses += assoc;
+ }
+
if (blk != NULL) {
// move this block to head of the MRU list
sets[set].moveToHead(blk);
@@ -216,6 +230,10 @@ LRU::insertBlock(PacketPtr pkt, BlkType *blk)
unsigned set = extractSet(addr);
sets[set].moveToHead(blk);
+
+ // We only need to write into one tag and one data block.
+ tagAccesses += 1;
+ dataAccesses += 1;
}
void
diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh
index 68c29b754..b9f8fc25c 100644
--- a/src/mem/cache/tags/lru.hh
+++ b/src/mem/cache/tags/lru.hh
@@ -81,6 +81,8 @@ class LRU : public BaseTags
const unsigned assoc;
/** The number of sets in the cache. */
const unsigned numSets;
+ /** Whether tags and data are accessed sequentially. */
+ const bool sequentialAccess;
/** The cache sets. */
SetType *sets;