mem-cache: Split array indexing and replacement policies.

Replacement policies (LRU, Random) are currently considered as array
indexing methods, but have completely different functionalities:

- Array indexers determine the possible locations for block allocation.
  This information is used to generate replacement candidates when
  conflicts happen.
- Replacement policies determine which of the replacement candidates
  should be evicted to make room for new allocations.

For this reason, they were split into different classes. Advantages:

- Easier and more straightforward to implement other replacement
  policies (RRIP, LFU, ARC, ...)
- Allow easier future implementation of cache organization schemes

As now we can't assure the use of sets, the previous way to create a
true LRU is not viable. Now a timestamp_bits parameter controls how
many bits are dedicated for the timestamp, and a true LRU can be
achieved through an infinite number of bits (although a few bits suffice
in practice).

Change-Id: I23750db121f1474d17831137e6ff618beb2b3eda
Reviewed-on: https://gem5-review.googlesource.com/8501
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
This commit is contained in:
Daniel R. Carvalho
2018-02-19 15:13:11 +01:00
committed by Daniel Carvalho
parent 0473286ab1
commit d207e9ccee
24 changed files with 555 additions and 351 deletions

View File

@@ -201,4 +201,5 @@ class O3_ARM_v7aL2(Cache):
clusivity = 'mostly_excl'
# Simple stride prefetcher
prefetcher = StridePrefetcher(degree=8, latency = 1)
tags = RandomRepl()
tags = BaseSetAssoc()
repl_policy = RandomRP()

View File

@@ -145,6 +145,5 @@ class L2(Cache):
clusivity = 'mostly_excl'
# Simple stride prefetcher
prefetcher = StridePrefetcher(degree=1, latency = 1)
tags = RandomRepl()
tags = BaseSetAssoc()
repl_policy = RandomRP()

View File

@@ -197,4 +197,5 @@ class L2(Cache):
clusivity = 'mostly_excl'
# Simple stride prefetcher
prefetcher = StridePrefetcher(degree=8, latency = 1)
tags = RandomRepl()
tags = BaseSetAssoc()
repl_policy = RandomRP()

View File

@@ -43,6 +43,7 @@ from m5.params import *
from m5.proxy import *
from MemObject import MemObject
from Prefetcher import BasePrefetcher
from ReplacementPolicies import *
from Tags import *
class BaseCache(MemObject):
@@ -74,7 +75,10 @@ class BaseCache(MemObject):
prefetch_on_access = Param.Bool(False,
"Notify the hardware prefetcher on every access (not just misses)")
tags = Param.BaseTags(LRU(), "Tag store (replacement policy)")
tags = Param.BaseTags(BaseSetAssoc(), "Tag store")
replacement_policy = Param.BaseReplacementPolicy(LRURP(),
"Replacement policy")
sequential_access = Param.Bool(False,
"Whether to access tags and data sequentially")

View File

@@ -52,8 +52,6 @@
#include "mem/cache/cache.hh"
#include "mem/cache/mshr.hh"
#include "mem/cache/tags/fa_lru.hh"
#include "mem/cache/tags/lru.hh"
#include "mem/cache/tags/random_repl.hh"
#include "sim/full_system.hh"
using namespace std;

14
src/mem/cache/blk.hh vendored
View File

@@ -99,7 +99,7 @@ class CacheBlk
/** The current status of this block. @sa CacheBlockStatusBits */
State status;
/** Which curTick() will this block be accessable */
/** Which curTick() will this block be accessible */
Tick whenReady;
/**
@@ -108,7 +108,10 @@ class CacheBlk
*/
int set, way;
/** whether this block has been touched */
/**
* Whether this block has been touched since simulation started.
* Used to calculate number of used tags.
*/
bool isTouched;
/** Number of references to this block since it was brought in. */
@@ -117,8 +120,15 @@ class CacheBlk
/** holds the source requestor ID for this block. */
int srcMasterId;
/** Tick on which the block was inserted in the cache. */
Tick tickInserted;
/**
* Replacement policy data. As of now it is only an update timestamp.
* Tick on which the block was last touched.
*/
Tick lastTouchTick;
protected:
/**
* Represents that the indicated thread context has a "lock" on

View File

@@ -1816,6 +1816,7 @@ Cache::invalidateVisitor(CacheBlk &blk)
CacheBlk*
Cache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks)
{
// Find replacement victim
CacheBlk *blk = tags->findVictim(addr);
// It is valid to return nullptr if there is no victim
@@ -2802,6 +2803,7 @@ Cache*
CacheParams::create()
{
assert(tags);
assert(replacement_policy);
return new Cache(this);
}

View File

@@ -0,0 +1,46 @@
# Copyright (c) 2018 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.
#
# Authors: Daniel Carvalho
from m5.params import *
from m5.proxy import *
from m5.SimObject import SimObject
class BaseReplacementPolicy(SimObject):
type = 'BaseReplacementPolicy'
abstract = True
cxx_header = "mem/cache/replacement_policies/base.hh"
class LRURP(BaseReplacementPolicy):
type = 'LRURP'
cxx_class = 'LRURP'
cxx_header = "mem/cache/replacement_policies/lru_rp.hh"
class RandomRP(BaseReplacementPolicy):
type = 'RandomRP'
cxx_class = 'RandomRP'
cxx_header = "mem/cache/replacement_policies/random_rp.hh"

View File

@@ -0,0 +1,37 @@
# -*- mode:python -*-
# Copyright (c) 2018 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.
#
# Authors: Daniel Carvalho
Import('*')
SimObject('ReplacementPolicies.py')
Source('base.cc')
Source('lru_rp.cc')
Source('random_rp.cc')

View File

@@ -0,0 +1,66 @@
/**
* Copyright (c) 2018 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.
*
* Authors: Daniel Carvalho
*/
/**
* @file
* Declaration of a common base class for cache replacement policy objects.
* In general replacement policies try to use invalid entries as victims,
* and if no such blocks exist the replacement policy is applied.
*/
#include "mem/cache/replacement_policies/base.hh"
BaseReplacementPolicy::BaseReplacementPolicy(const Params *p)
: SimObject(p)
{
}
void
BaseReplacementPolicy::touch(CacheBlk *blk)
{
// Inform block has been touched
blk->isTouched = true;
// Update frequency counter
blk->refCount++;
}
void
BaseReplacementPolicy::reset(CacheBlk *blk)
{
// Inform block has been touched
blk->isTouched = true;
// Set insertion tick
blk->tickInserted = curTick();
// Reset frequency counter
blk->refCount = 0;
}

View File

@@ -0,0 +1,105 @@
/**
* Copyright (c) 2018 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.
*
* Authors: Daniel Carvalho
*/
#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_BASE_HH__
#define __MEM_CACHE_REPLACEMENT_POLICIES_BASE_HH__
#include "mem/cache/base.hh"
#include "mem/cache/blk.hh"
#include "params/BaseReplacementPolicy.hh"
#include "sim/sim_object.hh"
/**
* Replacement candidates as chosen by the indexing policy.
*
* The base functions touch() and reset() must be called by all subclasses
* that override them.
*
* @todo
* Currently the replacement candidates are simply the cache blocks
* derived from the possible placement locations of an address, as
* defined by the getPossibleLocations() from BaseTags. In a future
* patch it should be an inheritable class to allow the replacement
* policies to be used with any table-like structure that needs to
* replace its entries.
*/
typedef std::vector<CacheBlk*> ReplacementCandidates;
/**
* A common base class of cache replacement policy objects.
*/
class BaseReplacementPolicy : public SimObject
{
public:
/**
* Convenience typedef.
*/
typedef BaseReplacementPolicyParams Params;
/**
* Construct and initiliaze this replacement policy.
*/
BaseReplacementPolicy(const Params *p);
/**
* Destructor.
*/
virtual ~BaseReplacementPolicy() {}
/**
* Touch a block to update its replacement data.
* Updates number of references.
*
* This base function must be called by all subclasses that override it.
*
* @param blk Cache block to be touched.
*/
virtual void touch(CacheBlk *blk);
/**
* Reset replacement data for a block. Used when a block is inserted.
* Sets the insertion tick, and update number of references.
*
* This base function must be called by all subclasses that override it.
*
* @param blk Cache block to be reset.
*/
virtual void reset(CacheBlk *blk);
/**
* Find replacement victim among candidates.
*
* @param candidates Replacement candidates, selected by indexing policy.
* @return Cache block to be replaced.
*/
virtual CacheBlk* getVictim(const ReplacementCandidates& candidates) = 0;
};
#endif // __MEM_CACHE_REPLACEMENT_POLICIES_BASE_HH__

View File

@@ -0,0 +1,87 @@
/**
* Copyright (c) 2018 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.
*
* Authors: Daniel Carvalho
*/
#include "mem/cache/replacement_policies/lru_rp.hh"
#include "debug/CacheRepl.hh"
LRURP::LRURP(const Params *p)
: BaseReplacementPolicy(p)
{
}
void
LRURP::touch(CacheBlk *blk)
{
BaseReplacementPolicy::touch(blk);
// Update last touch timestamp
blk->lastTouchTick = curTick();
}
void
LRURP::reset(CacheBlk *blk)
{
BaseReplacementPolicy::reset(blk);
// Set last touch timestamp
blk->lastTouchTick = blk->tickInserted;
}
CacheBlk*
LRURP::getVictim(const ReplacementCandidates& candidates)
{
// There must be at least one replacement candidate
assert(candidates.size() > 0);
// Visit all candidates to find victim
CacheBlk* blk = candidates[0];
for (const auto& candidate : candidates) {
// Stop iteration if found an invalid block
if (!candidate->isValid()) {
blk = candidate;
break;
// Update victim block if necessary
} else if (candidate->lastTouchTick < blk->lastTouchTick) {
blk = candidate;
}
}
DPRINTF(CacheRepl, "set %x, way %x: selecting blk for replacement\n",
blk->set, blk->way);
return blk;
}
LRURP*
LRURPParams::create()
{
return new LRURP(this);
}

View File

@@ -1,17 +1,5 @@
/*
* Copyright (c) 2012-2013 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2003-2005,2014 The Regents of The University of Michigan
/**
* Copyright (c) 2018 Inria
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,42 +25,60 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Erik Hallnor
* Authors: Daniel Carvalho
*/
/**
* @file
* Declaration of a LRU tag store.
* The LRU tags guarantee that the true least-recently-used way in
* a set will always be evicted.
* Declaration of a Least Recently Used replacement policy.
* The victim is chosen using the timestamp. The timestamp may be true or
* pseudo, depending on the quantity of bits allocated for that.
*/
#ifndef __MEM_CACHE_TAGS_LRU_HH__
#define __MEM_CACHE_TAGS_LRU_HH__
#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_LRU_RP_HH__
#define __MEM_CACHE_REPLACEMENT_POLICIES_LRU_RP_HH__
#include "mem/cache/tags/base_set_assoc.hh"
#include "params/LRU.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "params/LRURP.hh"
class LRU : public BaseSetAssoc
class LRURP : public BaseReplacementPolicy
{
public:
/** Convenience typedef. */
typedef LRUParams Params;
typedef LRURPParams Params;
/**
* Construct and initialize this tag store.
* Construct and initiliaze this replacement policy.
*/
LRU(const Params *p);
LRURP(const Params *p);
/**
* Destructor
* Destructor.
*/
~LRU() {}
~LRURP() {}
CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) override;
CacheBlk* findVictim(Addr addr) override;
void insertBlock(PacketPtr pkt, BlkType *blk) override;
void invalidate(CacheBlk *blk) override;
/**
* Touch a block to update its last touch tick.
*
* @param blk Cache block to be touched.
*/
void touch(CacheBlk *blk);
/**
* Reset replacement data for a block. Used when a block is inserted.
* Sets its last touch tick as the current tick.
*
* @param blk Cache block to be reset.
*/
void reset(CacheBlk *blk);
/**
* Find replacement victim using LRU timestamps.
*
* @param candidates Replacement candidates, selected by indexing policy.
* @return Cache block to be replaced.
*/
CacheBlk* getVictim(const ReplacementCandidates& candidates) override;
};
#endif // __MEM_CACHE_TAGS_LRU_HH__
#endif // __MEM_CACHE_REPLACEMENT_POLICIES_LRU_RP_HH__

View File

@@ -0,0 +1,71 @@
/**
* Copyright (c) 2018 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.
*
* Authors: Daniel Carvalho
*/
#include "mem/cache/replacement_policies/random_rp.hh"
#include "base/random.hh"
#include "debug/CacheRepl.hh"
RandomRP::RandomRP(const Params *p)
: BaseReplacementPolicy(p)
{
}
CacheBlk*
RandomRP::getVictim(const ReplacementCandidates& candidates)
{
// There must be at least one replacement candidate
assert(candidates.size() > 0);
// Choose one candidate at random
CacheBlk* blk = candidates[random_mt.random<unsigned>(0,
candidates.size() - 1)];
// Visit all candidates to find an invalid entry
for (const auto& candidate : candidates) {
// Give priority to victimise invalid entries
if (!candidate->isValid()){
blk = candidate;
break;
}
}
// If no invalid blocks were found, choose one of the candidates randomly
DPRINTF(CacheRepl, "set %x, way %x: selecting blk for replacement\n",
blk->set, blk->way);
return blk;
}
RandomRP*
RandomRPParams::create()
{
return new RandomRP(this);
}

View File

@@ -1,17 +1,5 @@
/*
* Copyright (c) 2017 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2014 The Regents of The University of Michigan
/**
* Copyright (c) 2018 Inria
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,42 +25,43 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Anthony Gutierrez
* Authors: Daniel Carvalho
*/
/**
* @file
* Declaration of a random replacement tag store.
* The RandomRepl tags first try to evict an invalid
* block. If no invalid blocks are found, a candidate
* for eviction is found at random.
* Declaration of a random replacement policy.
* The victim is chosen at random, if there are no invalid entries.
*/
#ifndef __MEM_CACHE_TAGS_RANDOM_REPL_HH__
#define __MEM_CACHE_TAGS_RANDOM_REPL_HH__
#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_RANDOM_RP_HH__
#define __MEM_CACHE_REPLACEMENT_POLICIES_RANDOM_RP_HH__
#include "mem/cache/tags/base_set_assoc.hh"
#include "params/RandomRepl.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "params/RandomRP.hh"
class RandomRepl : public BaseSetAssoc
class RandomRP : public BaseReplacementPolicy
{
public:
/** Convenience typedef. */
typedef RandomReplParams Params;
typedef RandomRPParams Params;
/**
* Construct and initiliaze this tag store.
* Construct and initiliaze this replacement policy.
*/
RandomRepl(const Params *p);
RandomRP(const Params *p);
/**
* Destructor
* Destructor.
*/
~RandomRepl() {}
~RandomRP() {}
CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat);
CacheBlk* findVictim(Addr addr);
void insertBlock(PacketPtr pkt, BlkType *blk);
/**
* Find replacement victim at random.
* @param candidates Replacement candidates, selected by indexing policy.
* @return Cache block to be replaced.
*/
CacheBlk* getVictim(const ReplacementCandidates& candidates) override;
};
#endif // __MEM_CACHE_TAGS_RANDOM_REPL_HH__
#endif // __MEM_CACHE_REPLACEMENT_POLICIES_RANDOM_RP_HH__

View File

@@ -34,6 +34,4 @@ SimObject('Tags.py')
Source('base.cc')
Source('base_set_assoc.cc')
Source('lru.cc')
Source('random_repl.cc')
Source('fa_lru.cc')

View File

@@ -66,19 +66,12 @@ class BaseTags(ClockedObject):
class BaseSetAssoc(BaseTags):
type = 'BaseSetAssoc'
abstract = True
cxx_header = "mem/cache/tags/base_set_assoc.hh"
assoc = Param.Int(Parent.assoc, "associativity")
class LRU(BaseSetAssoc):
type = 'LRU'
cxx_class = 'LRU'
cxx_header = "mem/cache/tags/lru.hh"
class RandomRepl(BaseSetAssoc):
type = 'RandomRepl'
cxx_class = 'RandomRepl'
cxx_header = "mem/cache/tags/random_repl.hh"
# Get replacement policy from the parent (cache)
replacement_policy = Param.BaseReplacementPolicy(
Parent.replacement_policy, "Replacement policy")
class FALRU(BaseTags):
type = 'FALRU'

View File

@@ -54,6 +54,7 @@
#include "base/callback.hh"
#include "base/statistics.hh"
#include "mem/cache/blk.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "params/BaseTags.hh"
#include "sim/clocked_object.hh"
@@ -249,6 +250,14 @@ class BaseTags : public ClockedObject
occupancies[blk->srcMasterId]--;
}
/**
* Find replacement victim based on address.
*
* @param addr Address to find a victim for.
* @return Cache block to be replaced.
*/
virtual CacheBlk* findVictim(Addr addr) = 0;
virtual CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) = 0;
virtual Addr extractTag(Addr addr) const = 0;
@@ -263,8 +272,6 @@ class BaseTags : public ClockedObject
*/
virtual Addr regenerateBlkAddr(const CacheBlk* blk) const = 0;
virtual CacheBlk* findVictim(Addr addr) = 0;
virtual int extractSet(Addr addr) const = 0;
virtual void forEachBlk(CacheBlkVisitor &visitor) = 0;

View File

@@ -60,7 +60,8 @@ BaseSetAssoc::BaseSetAssoc(const Params *p)
dataBlks(new uint8_t[p->size]), // Allocate data storage in one big chunk
numSets(p->size / (p->block_size * p->assoc)),
sequentialAccess(p->sequential_access),
sets(p->size / (p->block_size * p->assoc))
sets(p->size / (p->block_size * p->assoc)),
replacementPolicy(p->replacement_policy)
{
// Check parameters
if (blkSize < 4 || !isPowerOf2(blkSize)) {
@@ -184,3 +185,9 @@ BaseSetAssoc::computeStats()
}
}
}
BaseSetAssoc *
BaseSetAssocParams::create()
{
return new BaseSetAssoc(this);
}

View File

@@ -64,14 +64,9 @@
* A BaseSetAssoc cache tag store.
* @sa \ref gem5MemorySystem "gem5 Memory System"
*
* The BaseSetAssoc tags provide a base, as well as the functionality
* common to any set associative tags. Any derived class must implement
* the methods related to the specifics of the actual replacment policy.
* These are:
*
* BlkType* accessBlock();
* BlkType* findVictim();
* void insertBlock();
* The BaseSetAssoc placement policy divides the cache into s sets of w
* cache lines (ways). A cache line is mapped onto a set, and can be placed
* into any of the ways of this set.
*/
class BaseSetAssoc : public BaseTags
{
@@ -109,7 +104,10 @@ class BaseSetAssoc : public BaseTags
/** Mask out all bits that aren't part of the set index. */
unsigned setMask;
public:
/** Replacement policy */
BaseReplacementPolicy *replacementPolicy;
public:
/** Convenience typedef. */
typedef BaseSetAssocParams Params;
@@ -169,7 +167,9 @@ public:
lat = cache->ticksToCycles(blk->whenReady - curTick()) +
accessLatency;
}
blk->refCount += 1;
// Update replacement data of accessed block
replacementPolicy->touch(blk);
} else {
// If a cache miss
lat = lookupLatency;
@@ -189,25 +189,29 @@ public:
CacheBlk* findBlock(Addr addr, bool is_secure) const override;
/**
* Find an invalid block to evict for the address provided.
* If there are no invalid blocks, this will return the block
* in the least-recently-used position.
* @param addr The addr to a find a replacement candidate for.
* @return The candidate block.
* Find replacement victim based on address.
*
* @param addr Address to find a victim for.
* @return Cache block to be replaced.
*/
CacheBlk* findVictim(Addr addr) override
{
BlkType *blk = nullptr;
int set = extractSet(addr);
// Choose replacement victim from replacement candidates
return replacementPolicy->getVictim(getPossibleLocations(addr));
}
// prefer to evict an invalid block
for (int i = 0; i < allocAssoc; ++i) {
blk = sets[set].blks[i];
if (!blk->isValid())
break;
}
return blk;
/**
* 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)
{
return sets[extractSet(addr)].blks;
}
/**
@@ -242,9 +246,8 @@ public:
}
// Previous block, if existed, has been removed, and now we have
// to insert the new one and mark it as touched
// to insert the new one
tagsInUse++;
blk->isTouched = true;
// Set tag for new block. Caller is responsible for setting status.
blk->tag = extractTag(addr);
@@ -254,11 +257,12 @@ public:
occupancies[master_id]++;
blk->srcMasterId = master_id;
blk->task_id = task_id;
blk->tickInserted = curTick();
// We only need to write into one tag and one data block.
tagAccesses += 1;
dataAccesses += 1;
replacementPolicy->reset(blk);
}
/**

View File

@@ -98,7 +98,6 @@ FALRU::FALRU(const Params *p)
}
blks[i].prev = &(blks[i-1]);
blks[i].next = &(blks[i+1]);
blks[i].isTouched = false;
blks[i].set = 0;
blks[i].way = i;
}
@@ -255,13 +254,13 @@ FALRU::findVictim(Addr addr)
replacements[0]++;
} else {
tagsInUse++;
blk->isTouched = true;
if (!warmedUp && tagsInUse.value() >= warmupBound) {
warmedUp = true;
warmupCycle = curTick();
}
}
//assert(check());
return blk;
}

View File

@@ -67,8 +67,6 @@ public:
FALRUBlk *prev;
/** The next block in LRU order. */
FALRUBlk *next;
/** Has this block been touched? */
bool isTouched;
/**
* A bit mask of the sizes of cache that this block is resident in.
@@ -204,9 +202,10 @@ public:
CacheBlk* findBlock(Addr addr, bool is_secure) const override;
/**
* Find a replacement block for the address provided.
* @param pkt The request to a find a replacement candidate for.
* @return The block to place the replacement in.
* Find replacement victim based on address.
*
* @param addr Address to find a victim for.
* @return Cache block to be replaced.
*/
CacheBlk* findVictim(Addr addr) override;

View File

@@ -1,120 +0,0 @@
/*
* Copyright (c) 2012-2013 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2003-2005,2014 The Regents of The University of Michigan
* 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.
*
* Authors: Erik Hallnor
*/
/**
* @file
* Definitions of a LRU tag store.
*/
#include "mem/cache/tags/lru.hh"
#include "debug/CacheRepl.hh"
#include "mem/cache/base.hh"
LRU::LRU(const Params *p)
: BaseSetAssoc(p)
{
}
CacheBlk*
LRU::accessBlock(Addr addr, bool is_secure, Cycles &lat)
{
CacheBlk *blk = BaseSetAssoc::accessBlock(addr, is_secure, lat);
if (blk != nullptr) {
// move this block to head of the MRU list
sets[blk->set].moveToHead(blk);
DPRINTF(CacheRepl, "set %x: moving blk %x (%s) to MRU\n",
blk->set, regenerateBlkAddr(blk),
is_secure ? "s" : "ns");
}
return blk;
}
CacheBlk*
LRU::findVictim(Addr addr)
{
int set = extractSet(addr);
// grab a replacement candidate
BlkType *blk = nullptr;
for (int i = assoc - 1; i >= 0; i--) {
BlkType *b = sets[set].blks[i];
if (b->way < allocAssoc) {
blk = b;
break;
}
}
assert(!blk || blk->way < allocAssoc);
if (blk && blk->isValid()) {
DPRINTF(CacheRepl, "set %x: selecting blk %x for replacement\n",
set, regenerateBlkAddr(blk));
}
return blk;
}
void
LRU::insertBlock(PacketPtr pkt, BlkType *blk)
{
BaseSetAssoc::insertBlock(pkt, blk);
int set = extractSet(pkt->getAddr());
sets[set].moveToHead(blk);
}
void
LRU::invalidate(CacheBlk *blk)
{
BaseSetAssoc::invalidate(blk);
// should be evicted before valid blocks
int set = blk->set;
sets[set].moveToTail(blk);
}
LRU*
LRUParams::create()
{
return new LRU(this);
}

View File

@@ -1,105 +0,0 @@
/*
* Copyright (c) 2017 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2014 The Regents of The University of Michigan
* Copyright (c) 2016 ARM Limited
* 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.
*
* Authors: Anthony Gutierrez
*/
/**
* @file
* Definitions of a random replacement tag store.
*/
#include "mem/cache/tags/random_repl.hh"
#include "base/random.hh"
#include "debug/CacheRepl.hh"
#include "mem/cache/base.hh"
RandomRepl::RandomRepl(const Params *p)
: BaseSetAssoc(p)
{
}
CacheBlk*
RandomRepl::accessBlock(Addr addr, bool is_secure, Cycles &lat)
{
return BaseSetAssoc::accessBlock(addr, is_secure, lat);
}
CacheBlk*
RandomRepl::findVictim(Addr addr)
{
CacheBlk *blk = BaseSetAssoc::findVictim(addr);
unsigned set = extractSet(addr);
// if all blocks are valid, pick a replacement at random
if (blk && blk->isValid()) {
// find a random index within the bounds of the set
int idx = random_mt.random<int>(0, assoc - 1);
blk = sets[set].blks[idx];
// Enforce allocation limit
while (blk->way >= allocAssoc) {
idx = (idx + 1) % assoc;
blk = sets[set].blks[idx];
}
assert(idx < assoc);
assert(idx >= 0);
assert(blk->way < allocAssoc);
DPRINTF(CacheRepl, "set %x: selecting blk %x for replacement\n",
blk->set, regenerateBlkAddr(blk));
}
return blk;
}
void
RandomRepl::insertBlock(PacketPtr pkt, BlkType *blk)
{
BaseSetAssoc::insertBlock(pkt, blk);
}
RandomRepl*
RandomReplParams::create()
{
return new RandomRepl(this);
}