mem-cache: Add Signature-Based Hit Predictor replacement policy
Add the SHiP Replacement Policy, as described in "SHiP: Signature- based Hit Predictor for High Performance Caching", by Wu et al. Instruction Sequence signatures have not been implemented. Change-Id: I44f00d26eab4c96c9c5bc29740862a87356d30d1 Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38118 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:
committed by
Daniel Carvalho
parent
4a3e99fbcb
commit
24041d6b77
@@ -114,6 +114,31 @@ class NRURP(BRRIPRP):
|
||||
btp = 100
|
||||
num_bits = 1
|
||||
|
||||
class SHiPRP(BRRIPRP):
|
||||
type = 'SHiPRP'
|
||||
abstract = True
|
||||
cxx_class = 'replacement_policy::SHiP'
|
||||
cxx_header = "mem/cache/replacement_policies/ship_rp.hh"
|
||||
|
||||
shct_size = Param.Unsigned(16384, "Number of SHCT entries")
|
||||
# By default any value greater than 0 is enough to change insertion policy
|
||||
insertion_threshold = Param.Percent(1,
|
||||
"Percentage at which an entry changes insertion policy")
|
||||
# Always make hits mark entries as last to be evicted
|
||||
hit_priority = True
|
||||
# Let the predictor decide when to change insertion policy
|
||||
btp = 0
|
||||
|
||||
class SHiPMemRP(SHiPRP):
|
||||
type = 'SHiPMemRP'
|
||||
cxx_class = 'replacement_policy::SHiPMem'
|
||||
cxx_header = "mem/cache/replacement_policies/ship_rp.hh"
|
||||
|
||||
class SHiPPCRP(SHiPRP):
|
||||
type = 'SHiPPCRP'
|
||||
cxx_class = 'replacement_policy::SHiPPC'
|
||||
cxx_header = "mem/cache/replacement_policies/ship_rp.hh"
|
||||
|
||||
class TreePLRURP(BaseReplacementPolicy):
|
||||
type = 'TreePLRURP'
|
||||
cxx_class = 'replacement_policy::TreePLRU'
|
||||
|
||||
@@ -39,5 +39,6 @@ Source('lru_rp.cc')
|
||||
Source('mru_rp.cc')
|
||||
Source('random_rp.cc')
|
||||
Source('second_chance_rp.cc')
|
||||
Source('ship_rp.cc')
|
||||
Source('tree_plru_rp.cc')
|
||||
Source('weighted_lru_rp.cc')
|
||||
|
||||
171
src/mem/cache/replacement_policies/ship_rp.cc
vendored
Normal file
171
src/mem/cache/replacement_policies/ship_rp.cc
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright (c) 2019, 2020 Inria
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mem/cache/replacement_policies/ship_rp.hh"
|
||||
|
||||
#include "base/logging.hh"
|
||||
#include "params/SHiPMemRP.hh"
|
||||
#include "params/SHiPPCRP.hh"
|
||||
#include "params/SHiPRP.hh"
|
||||
|
||||
namespace replacement_policy
|
||||
{
|
||||
|
||||
SHiP::SHiPReplData::SHiPReplData(int num_bits)
|
||||
: BRRIPReplData(num_bits), signature(0), outcome(false)
|
||||
{
|
||||
}
|
||||
|
||||
SHiP::SignatureType
|
||||
SHiP::SHiPReplData::getSignature() const
|
||||
{
|
||||
return signature;
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::SHiPReplData::setSignature(SignatureType new_signature)
|
||||
{
|
||||
signature = new_signature;
|
||||
outcome = false;
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::SHiPReplData::setReReferenced()
|
||||
{
|
||||
outcome = true;
|
||||
}
|
||||
|
||||
bool
|
||||
SHiP::SHiPReplData::wasReReferenced() const
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
|
||||
SHiP::SHiP(const Params &p)
|
||||
: BRRIP(p), insertionThreshold(p.insertion_threshold / 100.0),
|
||||
SHCT(p.shct_size, SatCounter(numRRPVBits))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::invalidate(const std::shared_ptr<ReplacementData>& replacement_data)
|
||||
{
|
||||
std::shared_ptr<SHiPReplData> casted_replacement_data =
|
||||
std::static_pointer_cast<SHiPReplData>(replacement_data);
|
||||
|
||||
// The predictor is detrained when an entry that has not been re-
|
||||
// referenced since insertion is invalidated
|
||||
if (casted_replacement_data->wasReReferenced()) {
|
||||
SHCT[casted_replacement_data->getSignature()]--;
|
||||
}
|
||||
|
||||
BRRIP::invalidate(replacement_data);
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::touch(const std::shared_ptr<ReplacementData>& replacement_data,
|
||||
const PacketPtr pkt)
|
||||
{
|
||||
std::shared_ptr<SHiPReplData> casted_replacement_data =
|
||||
std::static_pointer_cast<SHiPReplData>(replacement_data);
|
||||
|
||||
// When a hit happens the SHCT entry indexed by the signature is
|
||||
// incremented
|
||||
SHCT[getSignature(pkt)]++;
|
||||
casted_replacement_data->setReReferenced();
|
||||
|
||||
// This was a hit; update replacement data accordingly
|
||||
BRRIP::touch(replacement_data);
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::touch(const std::shared_ptr<ReplacementData>& replacement_data)
|
||||
const
|
||||
{
|
||||
panic("Cant train SHiP's predictor without access information.");
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::reset(const std::shared_ptr<ReplacementData>& replacement_data,
|
||||
const PacketPtr pkt)
|
||||
{
|
||||
std::shared_ptr<SHiPReplData> casted_replacement_data =
|
||||
std::static_pointer_cast<SHiPReplData>(replacement_data);
|
||||
|
||||
// Get signature
|
||||
const SignatureType signature = getSignature(pkt);
|
||||
|
||||
// Store signature
|
||||
casted_replacement_data->setSignature(signature);
|
||||
|
||||
// If SHCT for signature is set, predict intermediate re-reference.
|
||||
// Predict distant re-reference otherwise
|
||||
BRRIP::reset(replacement_data);
|
||||
if (SHCT[signature].calcSaturation() >= insertionThreshold) {
|
||||
casted_replacement_data->rrpv--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SHiP::reset(const std::shared_ptr<ReplacementData>& replacement_data)
|
||||
const
|
||||
{
|
||||
panic("Cant train SHiP's predictor without access information.");
|
||||
}
|
||||
|
||||
std::shared_ptr<ReplacementData>
|
||||
SHiP::instantiateEntry()
|
||||
{
|
||||
return std::shared_ptr<ReplacementData>(new SHiPReplData(numRRPVBits));
|
||||
}
|
||||
|
||||
SHiPMem::SHiPMem(const SHiPMemRPParams &p) : SHiP(p) {}
|
||||
|
||||
SHiP::SignatureType
|
||||
SHiPMem::getSignature(const PacketPtr pkt) const
|
||||
{
|
||||
return static_cast<SignatureType>(pkt->getAddr() % SHCT.size());
|
||||
}
|
||||
|
||||
SHiPPC::SHiPPC(const SHiPPCRPParams &p) : SHiP(p) {}
|
||||
|
||||
SHiP::SignatureType
|
||||
SHiPPC::getSignature(const PacketPtr pkt) const
|
||||
{
|
||||
SignatureType signature;
|
||||
|
||||
if (pkt->req->hasPC()) {
|
||||
signature = static_cast<SignatureType>(pkt->req->getPC());
|
||||
} else {
|
||||
signature = NO_PC_SIGNATURE;
|
||||
}
|
||||
|
||||
return signature % SHCT.size();
|
||||
}
|
||||
|
||||
} // namespace replacement_policy
|
||||
189
src/mem/cache/replacement_policies/ship_rp.hh
vendored
Normal file
189
src/mem/cache/replacement_policies/ship_rp.hh
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright (c) 2019, 2020 Inria
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Declaration of a the SHiP Replacement Policy, as described in "SHiP:
|
||||
* Signature-based Hit Predictor for High Performance Caching", by
|
||||
* Wu et al.
|
||||
*/
|
||||
|
||||
#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_SHIP_RP_HH__
|
||||
#define __MEM_CACHE_REPLACEMENT_POLICIES_SHIP_RP_HH__
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler.hh"
|
||||
#include "base/sat_counter.hh"
|
||||
#include "mem/cache/replacement_policies/brrip_rp.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
struct SHiPRPParams;
|
||||
struct SHiPMemRPParams;
|
||||
struct SHiPPCRPParams;
|
||||
|
||||
GEM5_DEPRECATED_NAMESPACE(ReplacementPolicy, replacement_policy);
|
||||
namespace replacement_policy
|
||||
{
|
||||
|
||||
class SHiP : public BRRIP
|
||||
{
|
||||
protected:
|
||||
typedef std::size_t SignatureType;
|
||||
|
||||
/** SHiP-specific implementation of replacement data. */
|
||||
class SHiPReplData : public BRRIPReplData
|
||||
{
|
||||
private:
|
||||
/** Signature that caused the insertion of this entry. */
|
||||
SignatureType signature;
|
||||
|
||||
/** Outcome of insertion; set to one if entry is re-referenced. */
|
||||
bool outcome;
|
||||
|
||||
public:
|
||||
SHiPReplData(int num_bits);
|
||||
|
||||
/** Get entry's signature. */
|
||||
SignatureType getSignature() const;
|
||||
|
||||
/**
|
||||
* Set this entry's signature and reset outcome.
|
||||
*
|
||||
* @param signature New signature value/
|
||||
*/
|
||||
void setSignature(SignatureType signature);
|
||||
|
||||
/** Set that this entry has been re-referenced. */
|
||||
void setReReferenced();
|
||||
|
||||
/**
|
||||
* Get whether entry has been re-referenced since insertion.
|
||||
*
|
||||
* @return True if entry has been re-referenced since insertion.
|
||||
*/
|
||||
bool wasReReferenced() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Saturation percentage at which an entry starts being inserted as
|
||||
* intermediate re-reference.
|
||||
*/
|
||||
const double insertionThreshold;
|
||||
|
||||
/**
|
||||
* Signature History Counter Table; learns the re-reference behavior
|
||||
* of a signature. A zero entry provides a strong indication that
|
||||
* future lines brought by that signature will not receive any hits.
|
||||
*/
|
||||
std::vector<SatCounter8> SHCT;
|
||||
|
||||
/**
|
||||
* Extract signature from packet.
|
||||
*
|
||||
* @param pkt The packet to extract a signature from.
|
||||
* @return The signature extracted.
|
||||
*/
|
||||
virtual SignatureType getSignature(const PacketPtr pkt) const = 0;
|
||||
|
||||
public:
|
||||
typedef SHiPRPParams Params;
|
||||
SHiP(const Params &p);
|
||||
~SHiP() = default;
|
||||
|
||||
/**
|
||||
* Invalidate replacement data to set it as the next probable victim.
|
||||
* Updates predictor and invalidate data.
|
||||
*
|
||||
* @param replacement_data Replacement data to be invalidated.
|
||||
*/
|
||||
void invalidate(const std::shared_ptr<ReplacementData>& replacement_data)
|
||||
override;
|
||||
|
||||
/**
|
||||
* Touch an entry to update its replacement data.
|
||||
* Updates predictor and assigns RRPV values of Table 3.
|
||||
*
|
||||
* @param replacement_data Replacement data to be touched.
|
||||
* @param pkt Packet that generated this hit.
|
||||
*/
|
||||
void touch(const std::shared_ptr<ReplacementData>& replacement_data,
|
||||
const PacketPtr pkt) override;
|
||||
void touch(const std::shared_ptr<ReplacementData>& replacement_data) const
|
||||
override;
|
||||
|
||||
/**
|
||||
* Reset replacement data. Used when an entry is inserted.
|
||||
* Updates predictor and assigns RRPV values of Table 3.
|
||||
*
|
||||
* @param replacement_data Replacement data to be reset.
|
||||
* @param pkt Packet that generated this miss.
|
||||
*/
|
||||
void reset(const std::shared_ptr<ReplacementData>& replacement_data,
|
||||
const PacketPtr pkt) override;
|
||||
void reset(const std::shared_ptr<ReplacementData>& replacement_data) const
|
||||
override;
|
||||
|
||||
/**
|
||||
* Instantiate a replacement data entry.
|
||||
*
|
||||
* @return A shared pointer to the new replacement data.
|
||||
*/
|
||||
std::shared_ptr<ReplacementData> instantiateEntry() override;
|
||||
};
|
||||
|
||||
/** SHiP that Uses memory addresses as signatures. */
|
||||
class SHiPMem : public SHiP
|
||||
{
|
||||
protected:
|
||||
SignatureType getSignature(const PacketPtr pkt) const override;
|
||||
|
||||
public:
|
||||
SHiPMem(const SHiPMemRPParams &p);
|
||||
~SHiPMem() = default;
|
||||
};
|
||||
|
||||
/** SHiP that Uses PCs as signatures. */
|
||||
class SHiPPC : public SHiP
|
||||
{
|
||||
private:
|
||||
/** Signature to be used when no PC is provided in an access. */
|
||||
const SignatureType NO_PC_SIGNATURE = 0;
|
||||
|
||||
protected:
|
||||
SignatureType getSignature(const PacketPtr pkt) const override;
|
||||
|
||||
public:
|
||||
SHiPPC(const SHiPPCRPParams &p);
|
||||
~SHiPPC() = default;
|
||||
};
|
||||
|
||||
} // namespace replacement_policy
|
||||
|
||||
#endif // __MEM_CACHE_REPLACEMENT_POLICIES_SHIP_RP_HH__
|
||||
Reference in New Issue
Block a user