mem-cache: Use possible locations to find block

Use possible locations to find block to make it placement policy
independent.

Change-Id: I4c9d9e1e1ff91ce12e85ca1970f927d8f4f5a93b
Reviewed-on: https://gem5-review.googlesource.com/c/8884
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Daniel R. Carvalho
2018-03-09 15:04:20 +01:00
committed by Daniel Carvalho
parent 99a6c94e58
commit d204e56b2b
8 changed files with 120 additions and 85 deletions

View File

@@ -78,6 +78,35 @@ BaseTags::setCache(BaseCache *_cache)
cache = _cache;
}
std::vector<ReplaceableEntry*>
BaseTags::getPossibleLocations(const Addr addr) const
{
panic("Unimplemented getPossibleLocations for tags subclass");
}
CacheBlk*
BaseTags::findBlock(Addr addr, bool is_secure) const
{
// Extract block tag
Addr tag = extractTag(addr);
// Find possible locations for the given address
const std::vector<ReplaceableEntry*> locations =
getPossibleLocations(addr);
// Search for block
for (const auto& location : locations) {
CacheBlk* blk = static_cast<CacheBlk*>(location);
if ((blk->tag == tag) && blk->isValid() &&
(blk->isSecure() == is_secure)) {
return blk;
}
}
// Did not find block
return nullptr;
}
void
BaseTags::insertBlock(const Addr addr, const bool is_secure,
const int src_master_ID, const uint32_t task_ID,

View File

@@ -161,6 +161,18 @@ class BaseTags : public ClockedObject
*/
void setCache(BaseCache *_cache);
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
virtual std::vector<ReplaceableEntry*> getPossibleLocations(
const Addr addr) const;
public:
typedef BaseTagsParams Params;
BaseTags(const Params *p);
@@ -199,9 +211,13 @@ class BaseTags : public ClockedObject
std::string print();
/**
* Find a block using the memory address
* Finds the block in the cache without touching it.
*
* @param addr The address to look for.
* @param is_secure True if the target memory space is secure.
* @return Pointer to the cache block.
*/
virtual CacheBlk * findBlock(Addr addr, bool is_secure) const = 0;
virtual CacheBlk *findBlock(Addr addr, bool is_secure) const;
/**
* Find a block given set and way.

View File

@@ -84,14 +84,12 @@ BaseSetAssoc::init(BaseCache* cache)
// Initialize blocks
unsigned blkIndex = 0; // index into blks array
for (unsigned i = 0; i < numSets; ++i) {
sets[i].assoc = assoc;
sets[i].blks.resize(assoc);
sets[i].resize(assoc);
// link in the data blocks
for (unsigned j = 0; j < assoc; ++j) {
// Select block within the set to be linked
BlkType*& blk = sets[i].blks[j];
BlkType*& blk = sets[i][j];
// Locate next cache block
blk = &blks[blkIndex];
@@ -128,19 +126,10 @@ BaseSetAssoc::invalidate(CacheBlk *blk)
replacementPolicy->invalidate(blk->replacementData);
}
CacheBlk*
BaseSetAssoc::findBlock(Addr addr, bool is_secure) const
{
Addr tag = extractTag(addr);
unsigned set = extractSet(addr);
BlkType *blk = sets[set].findBlk(tag, is_secure);
return blk;
}
ReplaceableEntry*
BaseSetAssoc::findBlockBySetAndWay(int set, int way) const
{
return sets[set].blks[way];
return sets[set][way];
}
BaseSetAssoc *

View File

@@ -59,7 +59,6 @@
#include "mem/cache/blk.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "mem/cache/tags/base.hh"
#include "mem/cache/tags/cacheset.hh"
#include "params/BaseSetAssoc.hh"
/**
@@ -76,7 +75,7 @@ class BaseSetAssoc : public BaseTags
/** Typedef the block type used in this tag store. */
typedef CacheBlk BlkType;
/** Typedef the set type used in this tag store. */
typedef CacheSet<CacheBlk> SetType;
typedef std::vector<CacheBlk*> SetType;
protected:
/** The associativity of the cache. */
@@ -106,6 +105,25 @@ class BaseSetAssoc : public BaseTags
/** Replacement policy */
BaseReplacementPolicy *replacementPolicy;
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
override
{
std::vector<ReplaceableEntry*> locations;
for (const auto& blk : sets[extractSet(addr)]) {
locations.push_back(static_cast<ReplaceableEntry*>(blk));
}
return locations;
}
public:
/** Convenience typedef. */
typedef BaseSetAssocParams Params;
@@ -186,16 +204,6 @@ class BaseSetAssoc : public BaseTags
return blk;
}
/**
* Finds the given address in the cache, do not update replacement data.
* i.e. This is a no-side-effect find of a block.
*
* @param addr The address to find.
* @param is_secure True if the target memory space is secure.
* @return Pointer to the cache block if found.
*/
CacheBlk* findBlock(Addr addr, bool is_secure) const override;
/**
* Find a block given set and way.
*
@@ -218,7 +226,7 @@ class BaseSetAssoc : public BaseTags
std::vector<CacheBlk*>& evict_blks) const override
{
// Get possible locations for the victim block
std::vector<CacheBlk*> locations = getPossibleLocations(addr);
std::vector<ReplaceableEntry*> locations = getPossibleLocations(addr);
// Choose replacement victim from replacement candidates
CacheBlk* victim = static_cast<CacheBlk*>(replacementPolicy->getVictim(
@@ -234,20 +242,6 @@ class BaseSetAssoc : public BaseTags
return victim;
}
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
virtual const std::vector<CacheBlk*> getPossibleLocations(Addr addr) const
{
return sets[extractSet(addr)].blks;
}
/**
* Insert the new block into the cache and update replacement data.
*

View File

@@ -194,10 +194,14 @@ SectorTags::accessBlock(Addr addr, bool is_secure, Cycles &lat)
return blk;
}
const std::vector<SectorBlk*>
SectorTags::getPossibleLocations(Addr addr) const
std::vector<ReplaceableEntry*>
SectorTags::getPossibleLocations(const Addr addr) const
{
return sets[extractSet(addr)];
std::vector<ReplaceableEntry*> locations;
for (const auto& blk : sets[extractSet(addr)]) {
locations.push_back(static_cast<ReplaceableEntry*>(blk));
}
return locations;
}
void
@@ -238,11 +242,12 @@ SectorTags::findBlock(Addr addr, bool is_secure) const
const Addr offset = extractSectorOffset(addr);
// Find all possible sector locations for the given address
const std::vector<SectorBlk*> locations = getPossibleLocations(addr);
const std::vector<ReplaceableEntry*> locations =
getPossibleLocations(addr);
// Search for block
for (const auto& sector : locations) {
auto blk = sector->blks[offset];
auto blk = static_cast<SectorBlk*>(sector)->blks[offset];
if (blk->getTag() == tag && blk->isValid() &&
blk->isSecure() == is_secure) {
return blk;
@@ -264,16 +269,17 @@ SectorTags::findVictim(Addr addr, const bool is_secure,
std::vector<CacheBlk*>& evict_blks) const
{
// Get all possible locations of this sector
const std::vector<SectorBlk*> sector_locations =
const std::vector<ReplaceableEntry*> sector_locations =
getPossibleLocations(addr);
// Check if the sector this address belongs to has been allocated
Addr tag = extractTag(addr);
SectorBlk* victim_sector = nullptr;
for (const auto& sector : sector_locations){
if ((tag == sector->getTag()) && sector->isValid() &&
(is_secure == sector->isSecure())){
victim_sector = sector;
for (const auto& sector : sector_locations) {
SectorBlk* sector_blk = static_cast<SectorBlk*>(sector);
if ((tag == sector_blk->getTag()) && sector_blk->isValid() &&
(is_secure == sector_blk->isSecure())){
victim_sector = sector_blk;
break;
}
}
@@ -282,8 +288,7 @@ SectorTags::findVictim(Addr addr, const bool is_secure,
if (victim_sector == nullptr){
// Choose replacement victim from replacement candidates
victim_sector = static_cast<SectorBlk*>(replacementPolicy->getVictim(
std::vector<ReplaceableEntry*>(
sector_locations.begin(), sector_locations.end())));
sector_locations));
}
// Get the location of the victim block within the sector

View File

@@ -100,6 +100,18 @@ class SectorTags : public BaseTags
/** Mask out all bits that aren't part of the set index. */
const unsigned setMask;
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns sector blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
override;
public:
/** Convenience typedef. */
typedef SectorTagsParams Params;
@@ -142,18 +154,6 @@ class SectorTags : public BaseTags
*/
CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) override;
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns sector blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
virtual const std::vector<SectorBlk*> getPossibleLocations(Addr addr)
const;
/**
* Insert the new block into the cache and update replacement data.
*

View File

@@ -204,15 +204,15 @@ SkewedAssoc::regenerateBlkAddr(const CacheBlk* blk) const
return (blk->tag << tagShift) | (set << setShift);
}
const std::vector<CacheBlk*>
SkewedAssoc::getPossibleLocations(Addr addr) const
std::vector<ReplaceableEntry*>
SkewedAssoc::getPossibleLocations(const Addr addr) const
{
std::vector<CacheBlk*> locations;
std::vector<ReplaceableEntry*> locations;
// Parse all ways
for (int way = 0; way < assoc; ++way) {
// Apply hash to get set, and get way entry in it
locations.push_back(sets[extractSet(addr, way)].blks[way]);
locations.push_back(sets[extractSet(addr, way)][way]);
}
return locations;
@@ -225,10 +225,11 @@ SkewedAssoc::findBlock(Addr addr, bool is_secure) const
Addr tag = extractTag(addr);
// Find possible locations for the given address
std::vector<CacheBlk*> locations = getPossibleLocations(addr);
std::vector<ReplaceableEntry*> locations = getPossibleLocations(addr);
// Search for block
for (const auto& blk : locations) {
for (const auto& location : locations) {
CacheBlk* blk = static_cast<CacheBlk*>(location);
if ((blk->tag == tag) && blk->isValid() &&
(blk->isSecure() == is_secure)) {
return blk;

View File

@@ -120,6 +120,19 @@ class SkewedAssoc : public BaseSetAssoc
*/
unsigned extractSet(Addr addr, unsigned way) const;
protected:
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
override;
public:
/** Convenience typedef. */
typedef SkewedAssocParams Params;
@@ -134,18 +147,6 @@ class SkewedAssoc : public BaseSetAssoc
*/
~SkewedAssoc() {};
/**
* Find all possible block locations for insertion and replacement of
* an address. Should be called immediately before ReplacementPolicy's
* findVictim() not to break cache resizing.
* Returns blocks in all ways belonging to the set of the address.
*
* @param addr The addr to a find possible locations for.
* @return The possible locations.
*/
const std::vector<CacheBlk*> getPossibleLocations(Addr addr) const
override;
/**
* Finds the given address in the cache, do not update replacement data.
* i.e. This is a no-side-effect find of a block.