mem-cache: Allow sending packet information to replacement policy

Some replacement policies can use information such as address or
PC to improve their re-reference prediction.

Change-Id: I412eee09efa2f3511ca1ece76fc2732509df4745
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38117
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Daniel R. Carvalho
2019-06-01 15:48:27 +02:00
committed by Daniel Carvalho
parent ef99dc8310
commit 4a3e99fbcb
5 changed files with 50 additions and 7 deletions

View File

@@ -33,6 +33,7 @@
#include "base/compiler.hh"
#include "mem/cache/replacement_policies/replaceable_entry.hh"
#include "mem/packet.hh"
#include "params/BaseReplacementPolicy.hh"
#include "sim/sim_object.hh"
@@ -67,17 +68,29 @@ class Base : public SimObject
* Update replacement data.
*
* @param replacement_data Replacement data to be touched.
* @param pkt Packet that generated this access.
*/
virtual void touch(const std::shared_ptr<ReplacementData>&
replacement_data) const = 0;
replacement_data, const PacketPtr pkt)
{
touch(replacement_data);
}
virtual void touch(const std::shared_ptr<ReplacementData>&
replacement_data) const = 0;
/**
* Reset replacement data. Used when it's holder is inserted/validated.
*
* @param replacement_data Replacement data to be reset.
* @param pkt Packet that generated this access.
*/
virtual void reset(const std::shared_ptr<ReplacementData>&
replacement_data) const = 0;
replacement_data, const PacketPtr pkt)
{
reset(replacement_data);
}
virtual void reset(const std::shared_ptr<ReplacementData>&
replacement_data) const = 0;
/**
* Find replacement victim among candidates.

View File

@@ -53,6 +53,16 @@ Dueling::invalidate(const std::shared_ptr<ReplacementData>& replacement_data)
replPolicyB->invalidate(casted_replacement_data->replDataB);
}
void
Dueling::touch(const std::shared_ptr<ReplacementData>& replacement_data,
const PacketPtr pkt)
{
std::shared_ptr<DuelerReplData> casted_replacement_data =
std::static_pointer_cast<DuelerReplData>(replacement_data);
replPolicyA->touch(casted_replacement_data->replDataA, pkt);
replPolicyB->touch(casted_replacement_data->replDataB, pkt);
}
void
Dueling::touch(const std::shared_ptr<ReplacementData>& replacement_data) const
{
@@ -62,6 +72,22 @@ Dueling::touch(const std::shared_ptr<ReplacementData>& replacement_data) const
replPolicyB->touch(casted_replacement_data->replDataB);
}
void
Dueling::reset(const std::shared_ptr<ReplacementData>& replacement_data,
const PacketPtr pkt)
{
std::shared_ptr<DuelerReplData> casted_replacement_data =
std::static_pointer_cast<DuelerReplData>(replacement_data);
replPolicyA->reset(casted_replacement_data->replDataA, pkt);
replPolicyB->reset(casted_replacement_data->replDataB, pkt);
// A miss in a set is a sample to the duel. A call to this function
// implies in the replacement of an entry, which was either caused by
// a miss, an external invalidation, or the initialization of the table
// entry (when warming up)
duelingMonitor.sample(static_cast<Dueler*>(casted_replacement_data.get()));
}
void
Dueling::reset(const std::shared_ptr<ReplacementData>& replacement_data) const
{

View File

@@ -97,8 +97,12 @@ class Dueling : public Base
void invalidate(const std::shared_ptr<ReplacementData>& replacement_data)
override;
void touch(const std::shared_ptr<ReplacementData>& replacement_data,
const PacketPtr pkt) override;
void touch(const std::shared_ptr<ReplacementData>& replacement_data) const
override;
void reset(const std::shared_ptr<ReplacementData>& replacement_data,
const PacketPtr pkt) override;
void reset(const std::shared_ptr<ReplacementData>& replacement_data) const
override;
ReplaceableEntry* getVictim(const ReplacementCandidates& candidates) const

View File

@@ -143,7 +143,7 @@ class BaseSetAssoc : public BaseTags
blk->increaseRefCount();
// Update replacement data of accessed block
replacementPolicy->touch(blk->replacementData);
replacementPolicy->touch(blk->replacementData, pkt);
}
// The tag lookup latency is the same for a hit or a miss
@@ -195,7 +195,7 @@ class BaseSetAssoc : public BaseTags
stats.tagsInUse++;
// Update replacement policy
replacementPolicy->reset(blk->replacementData);
replacementPolicy->reset(blk->replacementData, pkt);
}
void moveBlock(CacheBlk *src_blk, CacheBlk *dest_blk) override;

View File

@@ -163,7 +163,7 @@ SectorTags::accessBlock(const PacketPtr pkt, Cycles &lat)
// Update replacement data of accessed block, which is shared with
// the whole sector it belongs to
replacementPolicy->touch(sector_blk->replacementData);
replacementPolicy->touch(sector_blk->replacementData, pkt);
}
// The tag lookup latency is the same for a hit or a miss
@@ -183,14 +183,14 @@ SectorTags::insertBlock(const PacketPtr pkt, CacheBlk *blk)
// sector was not previously present in the cache.
if (sector_blk->isValid()) {
// An existing entry's replacement data is just updated
replacementPolicy->touch(sector_blk->replacementData);
replacementPolicy->touch(sector_blk->replacementData, pkt);
} else {
// Increment tag counter
stats.tagsInUse++;
assert(stats.tagsInUse.value() <= numSectors);
// A new entry resets the replacement data
replacementPolicy->reset(sector_blk->replacementData);
replacementPolicy->reset(sector_blk->replacementData, pkt);
}
// Do common block insertion functionality