diff --git a/configs/example/cache_partitioning.py b/configs/example/cache_partitioning.py new file mode 100644 index 0000000000..2e204b225c --- /dev/null +++ b/configs/example/cache_partitioning.py @@ -0,0 +1,199 @@ +# Copyright (c) 2024 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. +# +# 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. + +# This script showcases the functionality of cache partitioning policies, +# containg a simple system comprised of a memory requestor (TrafficGen), +# a cache enforcing policies for requests and a SimpleMemory backing store. +# +# Using the Way policy, the cache should show the following statistics in the +# provided configuration: +# +# | Allocated Ways | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +# |----------------|---|-----|-----|-----|-----|-----|-----|------| +# | Cache Hits | 0 | 256 | 384 | 512 | 640 | 768 | 896 | 1024 | +# +# Using the MaxCapacity policy, expected results are the following: +# +# | Allocation % | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100 | +# |--------------|----|-----|-----|-----|-----|-----|-----|-----|-----|------| +# | Cache Hits | 0 | 152 | 307 | 409 | 512 | 614 | 716 | 819 | 921 | 1024 | + +import argparse + +import m5 +from m5.objects import * + + +def capacityAllocation(capacity_str): + """ + Verify that Max Capacity partitioning policy has been provided with a suitable + configuration + """ + capacity = float(capacity_str) + + if capacity > 1 or capacity < 0: + raise argparse.ArgumentTypeError( + "Max Capacity Policy needs allocation in range [0, 1]" + ) + + return capacity + + +def wayAllocation(way_str): + """ + Verify that Way partitioning policy has been provided with a suitable + configuration + """ + way_alloc = int(way_str) + + if way_alloc < 0: + raise argparse.ArgumentTypeError( + "Way Policy needs positive number of ways" + ) + + return way_alloc + + +def generatePartPolicy(args): + """ + Generate Partitioning Policy object based on provided arguments + """ + assert args.policy in [ + "way", + "max_capacity", + ], "Only support generating way and max_capacity policies" + + if args.policy == "way": + allocated_ways = [way for way in range(0, args.way_allocation)] + allocation = WayPolicyAllocation(partition_id=0, ways=allocated_ways) + + return WayPartitioningPolicy(allocations=[allocation]) + + if args.policy == "max_capacity": + return MaxCapacityPartitioningPolicy( + partition_ids=[0], capacities=[args.capacity_allocation] + ) + + +def configSystem(): + """ + Configure base system and memory + """ + + system = System(membus=IOXBar(width=128)) + system.clk_domain = SrcClockDomain( + clock="10THz", + voltage_domain=VoltageDomain(), + ) + + # Memory configuration + system.mem_ctrl = SimpleMemory(bandwidth="1GiB/s", latency="10ns") + + # add memory + system.mem_ctrl.range = AddrRange("64KiB") + system.mem_ctrl.port = system.membus.mem_side_ports + return system + + +parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter +) + +parser.add_argument( + "--policy", + default="way", + choices=["way", "max_capacity"], + help="This option defines which Cache Partitioning Policy to use for " + "the system cache", +) + +parser.add_argument( + "--capacity-allocation", + type=capacityAllocation, + default=0.5, + help="The amount of the cache to partition to the default PartitionID " + "when using Max Capacity Cache Partitioning Policy in [0,1] range", +) + +parser.add_argument( + "--way-allocation", + type=wayAllocation, + default=4, + help="The number of ways in the cache to partition to the default " + "PartitionID when using Way Cache Partitioning Policy", +) + +args = parser.parse_args() + +m5.ticks.setGlobalFrequency("10THz") +system = configSystem() + +# create a cache to sit between the memory and traffic gen to enforce +# partitioning policies +partition_policy = generatePartPolicy(args) +system.cache = NoncoherentCache( + size="64KiB", + assoc=8, + partitioning_policies=[partition_policy], + tag_latency=0, + data_latency=0, + response_latency=0, + mshrs=1, + tgts_per_mshr=8, + write_buffers=1, + replacement_policy=MRURP(), +) +system.cache.mem_side = system.membus.cpu_side_ports + +# instantiate traffic gen and connect to crossbar +system.tgen = PyTrafficGen() +system.tgen.port = system.cache.cpu_side + +# finalise config and run simulation +root = Root(full_system=False, system=system) +root.system.mem_mode = "timing" +m5.instantiate() + +# configure traffic generator to do 2x 64KiB sequential reads from address 0 +# to 65536; one to warm up the cache one to test cache partitioning +linear_tgen = system.tgen.createLinear( + 1000000000, 0, 65536, 64, 1, 1, 100, 65536 +) +exit_tgen = system.tgen.createExit(1) +system.tgen.start([linear_tgen, linear_tgen, exit_tgen]) + +# handle exit reporting +exit_event = m5.simulate(2000000000) +print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}") diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py index c1b1b95648..874182a9f8 100644 --- a/src/mem/cache/Cache.py +++ b/src/mem/cache/Cache.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013, 2015, 2018, 2023 ARM Limited +# Copyright (c) 2012-2013, 2015, 2018, 2023-2024 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -111,6 +111,12 @@ class BaseCache(ClockedObject): replacement_policy = Param.BaseReplacementPolicy( LRURP(), "Replacement policy" ) + partitioning_policies = VectorParam.BasePartitioningPolicy( + [], + "Partitioning policies " + "Setting multiple policies will enforce all of them individually " + "in order", + ) compressor = Param.BaseCacheCompressor(NULL, "Cache compressor.") replace_expansions = Param.Bool( diff --git a/src/mem/cache/SConscript b/src/mem/cache/SConscript index dd8f2b145b..248eb6db6e 100644 --- a/src/mem/cache/SConscript +++ b/src/mem/cache/SConscript @@ -1,5 +1,16 @@ # -*- mode:python -*- - +# Copyright (c) 2023-2024 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) 2006 The Regents of The University of Michigan # All rights reserved. # @@ -50,9 +61,11 @@ DebugFlag('CacheVerbose') DebugFlag('HWPrefetch') DebugFlag('MSHR') DebugFlag('HWPrefetchQueue') +DebugFlag('PartitionPolicy') # CacheTags is so outrageously verbose, printing the cache's entire tag # array on each timing access, that you should probably have to ask for # it explicitly even above and beyond CacheAll. CompoundFlag('CacheAll', ['Cache', 'CacheComp', 'CachePort', 'CacheRepl', - 'CacheVerbose', 'HWPrefetch', 'MSHR']) + 'CacheVerbose', 'HWPrefetch', 'MSHR', + 'PartitionPolicy']) diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index e738167066..095dea5e63 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, 2018-2019, 2023 ARM Limited + * Copyright (c) 2012-2013, 2018-2019, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -58,6 +58,7 @@ #include "mem/cache/prefetch/base.hh" #include "mem/cache/queue_entry.hh" #include "mem/cache/tags/compressed_tags.hh" +#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" #include "mem/cache/tags/super_blk.hh" #include "params/BaseCache.hh" #include "params/WriteAllocator.hh" @@ -1030,7 +1031,8 @@ BaseCache::updateCompressionData(CacheBlk *&blk, const uint64_t* data, CacheBlk *victim = nullptr; if (replaceExpansions || is_data_contraction) { victim = tags->findVictim(regenerateBlkAddr(blk), - blk->isSecure(), compression_size, evict_blks); + blk->isSecure(), compression_size, evict_blks, + blk->getPartitionId()); // It is valid to return nullptr if there is no victim if (!victim) { @@ -1639,10 +1641,12 @@ BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks) blk_size_bits = comp_data->getSizeBits(); } + // get partitionId from Packet + const auto partition_id = partitioning_policy::readPacketPartitionID(pkt); // Find replacement victim std::vector evict_blks; CacheBlk *victim = tags->findVictim(addr, is_secure, blk_size_bits, - evict_blks); + evict_blks, partition_id); // It is valid to return nullptr if there is no victim if (!victim) diff --git a/src/mem/cache/cache_blk.cc b/src/mem/cache/cache_blk.cc index 3ae37c1b6d..d1f8abcd74 100644 --- a/src/mem/cache/cache_blk.cc +++ b/src/mem/cache/cache_blk.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013 ARM Limited + * Copyright (c) 2012-2013, 2023-2024 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -48,7 +48,8 @@ namespace gem5 void CacheBlk::insert(const Addr tag, const bool is_secure, - const int src_requestor_ID, const uint32_t task_ID) + const int src_requestor_ID, const uint32_t task_ID, + const uint64_t partition_id) { // Make sure that the block has been properly invalidated assert(!isValid()); @@ -61,6 +62,9 @@ CacheBlk::insert(const Addr tag, const bool is_secure, // Set task ID setTaskId(task_ID); + // Set partition ID + setPartitionId(partition_id); + // Set insertion tick as current tick setTickInserted(); diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index e476ab639d..ad84def8e4 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 ARM Limited + * Copyright (c) 2012-2018, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,7 @@ class CacheBlk : public TaggedEntry } setCoherenceBits(other.coherence); setTaskId(other.getTaskId()); + setPartitionId(other.getPartitionId()); setWhenReady(curTick()); setRefCount(other.getRefCount()); setSrcRequestorId(other.getSrcRequestorId()); @@ -205,6 +207,7 @@ class CacheBlk : public TaggedEntry clearCoherenceBits(AllBits); setTaskId(context_switch_task_id::Unknown); + setPartitionId(std::numeric_limits::max()); setWhenReady(MaxTick); setRefCount(0); setSrcRequestorId(Request::invldRequestorId); @@ -287,6 +290,9 @@ class CacheBlk : public TaggedEntry /** Get the requestor id associated to this block. */ uint32_t getSrcRequestorId() const { return _srcRequestorId; } + /** Getter for _partitionId */ + uint64_t getPartitionId() const { return _partitionId; } + /** Get the number of references to this block since insertion. */ unsigned getRefCount() const { return _refCount; } @@ -315,9 +321,11 @@ class CacheBlk : public TaggedEntry * @param is_secure Whether the block is in secure space or not. * @param src_requestor_ID The source requestor ID. * @param task_ID The new task ID. + * @param partition_id The source partition ID. */ void insert(const Addr tag, const bool is_secure, - const int src_requestor_ID, const uint32_t task_ID); + const int src_requestor_ID, const uint32_t task_ID, + const uint64_t partition_id); using TaggedEntry::insert; /** @@ -466,6 +474,10 @@ class CacheBlk : public TaggedEntry /** Set the source requestor id. */ void setSrcRequestorId(const uint32_t id) { _srcRequestorId = id; } + /** Setter for _partitionId */ + void + setPartitionId(const uint64_t partitionId) { _partitionId = partitionId; } + /** Set the number of references to this block since insertion. */ void setRefCount(const unsigned count) { _refCount = count; } @@ -479,6 +491,10 @@ class CacheBlk : public TaggedEntry /** holds the source requestor ID for this block. */ int _srcRequestorId = 0; + /** Partition ID of the activity that allocated this block */ + /* This ID is used to enforce resource partitioning policies */ + uint64_t _partitionId; + /** Number of references to this block since it was brought in. */ unsigned _refCount = 0; diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py index 2717373829..3dbd526b35 100644 --- a/src/mem/cache/tags/Tags.py +++ b/src/mem/cache/tags/Tags.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013 ARM Limited +# Copyright (c) 2012-2013, 2023-2024 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -75,6 +75,10 @@ class BaseTags(ClockedObject): SetAssociative(), "Indexing policy" ) + partitioning_policies = VectorParam.BasePartitioningPolicy( + Parent.partitioning_policies, "Partitioning policies" + ) + # Set the indexing entry size as the block size entry_size = Param.Int( Parent.cache_line_size, "Indexing entry size in bytes" diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc index 8216f3dfe8..c7e529ef0c 100644 --- a/src/mem/cache/tags/base.cc +++ b/src/mem/cache/tags/base.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013,2016,2018-2019 ARM Limited + * Copyright (c) 2013, 2016, 2018-2019, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -50,6 +50,7 @@ #include "base/types.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" #include "mem/request.hh" #include "sim/core.hh" #include "sim/sim_exit.hh" @@ -62,6 +63,7 @@ BaseTags::BaseTags(const Params &p) : ClockedObject(p), blkSize(p.block_size), blkMask(blkSize - 1), size(p.size), lookupLatency(p.tag_latency), system(p.system), indexingPolicy(p.indexing_policy), + partitioningPolicies(p.partitioning_policies), warmupBound((p.warmup_percentage/100.0) * (p.size / p.block_size)), warmedUp(false), numBlocks(p.size / p.block_size), dataBlks(new uint8_t[p.size]), // Allocate data storage in one big chunk @@ -111,9 +113,10 @@ BaseTags::insertBlock(const PacketPtr pkt, CacheBlk *blk) assert(requestor_id < system->maxRequestors()); stats.occupancies[requestor_id]++; - // Insert block with tag, src requestor id and task id + // Insert block with tag, src requestor id, task id and PartitionId + const auto partition_id = partitioning_policy::readPacketPartitionID(pkt); blk->insert(extractTag(pkt->getAddr()), pkt->isSecure(), requestor_id, - pkt->req->taskId()); + pkt->req->taskId(), partition_id); // Check if cache warm up is done if (!warmedUp && stats.tagsInUse.value() >= warmupBound) { diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh index c49188151c..307159ae1d 100644 --- a/src/mem/cache/tags/base.hh +++ b/src/mem/cache/tags/base.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014,2016-2019 ARM Limited + * Copyright (c) 2012-2014, 2016-2019, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -56,6 +56,7 @@ #include "base/statistics.hh" #include "base/types.hh" #include "mem/cache/cache_blk.hh" +#include "mem/cache/tags/partitioning_policies/base_pp.hh" #include "mem/packet.hh" #include "params/BaseTags.hh" #include "sim/clocked_object.hh" @@ -88,6 +89,10 @@ class BaseTags : public ClockedObject /** Indexing policy */ BaseIndexingPolicy *indexingPolicy; + /** Partitioning policies */ + std::vector + partitioningPolicies; + /** * The number of tags that need to be touched to meet the warmup * percentage. @@ -276,11 +281,13 @@ class BaseTags : public ClockedObject * @param is_secure True if the target memory space is secure. * @param size Size, in bits, of new block to allocate. * @param evict_blks Cache blocks to be evicted. + * @param partition_id Partition ID for resource management. * @return Cache block to be replaced. */ virtual CacheBlk* findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) = 0; + std::vector& evict_blks, + const uint64_t partition_id=0) = 0; /** * Access block and update replacement data. May not succeed, in which case diff --git a/src/mem/cache/tags/base_set_assoc.cc b/src/mem/cache/tags/base_set_assoc.cc index b0cae8ec45..1973967d1b 100644 --- a/src/mem/cache/tags/base_set_assoc.cc +++ b/src/mem/cache/tags/base_set_assoc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 ARM Limited + * Copyright (c) 2012-2014, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -88,6 +88,10 @@ BaseSetAssoc::tagsInit() void BaseSetAssoc::invalidate(CacheBlk *blk) { + // Notify partitioning policies of release of ownership + for (auto partitioning_policy : partitioningPolicies) + partitioning_policy->notifyRelease(blk->getPartitionId()); + BaseTags::invalidate(blk); // Decrease the number of tags in use diff --git a/src/mem/cache/tags/base_set_assoc.hh b/src/mem/cache/tags/base_set_assoc.hh index 8ffb7189b7..db5fe605a7 100644 --- a/src/mem/cache/tags/base_set_assoc.hh +++ b/src/mem/cache/tags/base_set_assoc.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014,2017 ARM Limited + * Copyright (c) 2012-2014, 2017, 2023-2024 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -59,6 +59,7 @@ #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/base.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" #include "mem/packet.hh" #include "params/BaseSetAssoc.hh" @@ -163,19 +164,25 @@ class BaseSetAssoc : public BaseTags * @param is_secure True if the target memory space is secure. * @param size Size, in bits, of new block to allocate. * @param evict_blks Cache blocks to be evicted. + * @param partition_id Partition ID for resource management. * @return Cache block to be replaced. */ CacheBlk* findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) override + std::vector& evict_blks, + const uint64_t partition_id=0) override { // Get possible entries to be victimized - const std::vector entries = + std::vector entries = indexingPolicy->getPossibleEntries(addr); + // Filter entries based on PartitionID + for (auto partitioning_policy : partitioningPolicies) + partitioning_policy->filterByPartition(entries, partition_id); + // Choose replacement victim from replacement candidates - CacheBlk* victim = static_cast(replacementPolicy->getVictim( - entries)); + CacheBlk* victim = entries.empty() ? nullptr : + static_cast(replacementPolicy->getVictim(entries)); // There is only one eviction for this replacement evict_blks.push_back(victim); @@ -197,6 +204,14 @@ class BaseSetAssoc : public BaseTags // Increment tag counter stats.tagsInUse++; + // Notify partitioning policies of acquisition of ownership + for (auto & partitioning_policy : partitioningPolicies) { + // get partitionId from Packet + const auto partitionId = + partitioning_policy::readPacketPartitionID(pkt); + partitioning_policy->notifyAcquire(partitionId); + } + // Update replacement policy replacementPolicy->reset(blk->replacementData, pkt); } diff --git a/src/mem/cache/tags/compressed_tags.cc b/src/mem/cache/tags/compressed_tags.cc index c84718f5f6..96afd635aa 100644 --- a/src/mem/cache/tags/compressed_tags.cc +++ b/src/mem/cache/tags/compressed_tags.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2023-2024 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) 2018 Inria * All rights reserved. * @@ -104,12 +116,19 @@ CompressedTags::tagsInit() CacheBlk* CompressedTags::findVictim(Addr addr, const bool is_secure, const std::size_t compressed_size, - std::vector& evict_blks) + std::vector& evict_blks, + const uint64_t partition_id=0) { // Get all possible locations of this superblock - const std::vector superblock_entries = + std::vector superblock_entries = indexingPolicy->getPossibleEntries(addr); + // Filter entries based on PartitionID + for (auto partitioning_policy : partitioningPolicies){ + partitioning_policy->filterByPartition(superblock_entries, + partition_id); + } + // Check if the superblock this address belongs to has been allocated. If // so, try co-allocating Addr tag = extractTag(addr); @@ -132,6 +151,13 @@ CompressedTags::findVictim(Addr addr, const bool is_secure, // If the superblock is not present or cannot be co-allocated a // superblock must be replaced if (victim_superblock == nullptr){ + // check if partitioning policy limited allocation and if true - return + // this assumes that superblock_entries would not be empty if + // partitioning policy is not in place + if (superblock_entries.size() == 0){ + return nullptr; + } + // Choose replacement victim from replacement candidates victim_superblock = static_cast( replacementPolicy->getVictim(superblock_entries)); diff --git a/src/mem/cache/tags/compressed_tags.hh b/src/mem/cache/tags/compressed_tags.hh index 6e5b62d3e8..136a11fc5c 100644 --- a/src/mem/cache/tags/compressed_tags.hh +++ b/src/mem/cache/tags/compressed_tags.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2023-2024 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) 2018 Inria * All rights reserved. * @@ -102,11 +114,13 @@ class CompressedTags : public SectorTags * @param is_secure True if the target memory space is secure. * @param compressed_size Size, in bits, of new block to allocate. * @param evict_blks Cache blocks to be evicted. + * @param partition_id Partition ID for resource management. * @return Cache block to be replaced. */ CacheBlk* findVictim(Addr addr, const bool is_secure, const std::size_t compressed_size, - std::vector& evict_blks) override; + std::vector& evict_blks, + const uint64_t partition_id) override; /** * Find if any of the sub-blocks satisfies a condition. diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index 81fd478e59..1937ec2b25 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -1,4 +1,5 @@ /* + * Copyright (c) 2023-2024 ARM Limited * Copyright (c) 2018 Inria * Copyright (c) 2013,2016-2018 ARM Limited * All rights reserved. @@ -74,6 +75,8 @@ FALRU::FALRU(const Params &p) blkSize); if (!isPowerOf2(size)) fatal("Cache Size must be power of 2 for now"); + if (this->partitioningPolicies.size() != 0) + fatal("Cannot use Cache Partitioning Policies with FALRU"); blks = new FALRUBlk[numBlocks]; } @@ -191,7 +194,8 @@ FALRU::findBlockBySetAndWay(int set, int way) const CacheBlk* FALRU::findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) + std::vector& evict_blks, + const uint64_t partition_id) { // The victim is always stored on the tail for the FALRU FALRUBlk* victim = tail; diff --git a/src/mem/cache/tags/fa_lru.hh b/src/mem/cache/tags/fa_lru.hh index dba89f809d..9c49db4648 100644 --- a/src/mem/cache/tags/fa_lru.hh +++ b/src/mem/cache/tags/fa_lru.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2023-2024 ARM Limited * Copyright (c) 2012-2013,2016,2018 ARM Limited * All rights reserved. * @@ -216,11 +217,13 @@ class FALRU : public BaseTags * @param is_secure True if the target memory space is secure. * @param size Size, in bits, of new block to allocate. * @param evict_blks Cache blocks to be evicted. + * @param partition_id Partition ID for resource management. * @return Cache block to be replaced. */ CacheBlk* findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) override; + std::vector& evict_blks, + const uint64_t partition_id=0) override; /** * Insert the new block into the cache and update replacement data. diff --git a/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py new file mode 100644 index 0000000000..74ef6c5113 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py @@ -0,0 +1,95 @@ +# Copyright (c) 2024 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. + +from m5.params import ( + Param, + VectorParam, +) +from m5.proxy import Parent +from m5.SimObject import SimObject + + +class BasePartitioningPolicy(SimObject): + type = "BasePartitioningPolicy" + cxx_header = "mem/cache/tags/partitioning_policies/base_pp.hh" + cxx_class = "gem5::partitioning_policy::BasePartitioningPolicy" + abstract = True + + +class WayPolicyAllocation(SimObject): + type = "WayPolicyAllocation" + cxx_header = "mem/cache/tags/partitioning_policies/way_allocation.hh" + cxx_class = "gem5::partitioning_policy::WayPolicyAllocation" + + partition_id = Param.UInt64( + "PartitionID to use the allocated ways" "Example: 0" + ) + + ways = VectorParam.UInt64( + "Ways to be allocated to the provided PartitionID" + "Format: [,, ...]" + "Example: [0, 1]" + ) + + +class WayPartitioningPolicy(BasePartitioningPolicy): + type = "WayPartitioningPolicy" + cxx_header = "mem/cache/tags/partitioning_policies/way_pp.hh" + cxx_class = "gem5::partitioning_policy::WayPartitioningPolicy" + + cache_associativity = Param.Unsigned(Parent.assoc, "Associativity") + + allocations = VectorParam.WayPolicyAllocation( + "Array of WayPolicyAllocation objects, used to determine what will be" + "done in each cache way" + "Format: [,, ...]" + "Example: [" + " WayPolicyAllocation(0, [0,1,2,3])," + " WayPolicyAllocation(1, [4,5,6,7])" + "]" + ) + + +class MaxCapacityPartitioningPolicy(BasePartitioningPolicy): + type = "MaxCapacityPartitioningPolicy" + cxx_header = "mem/cache/tags/partitioning_policies/max_capacity_pp.hh" + cxx_class = "gem5::partitioning_policy::MaxCapacityPartitioningPolicy" + + cache_size = Param.MemorySize(Parent.size, "Cache size in bytes") + blk_size = Param.Int(Parent.cache_line_size, "Cache block size in bytes") + + partition_ids = VectorParam.UInt64( + "PartitionIDs assigned to this policy" + "Format: [,, ...]" + "Example: [0, 1]" + ) + + capacities = VectorParam.Float( + "Assigned max capacity in range [0,1] for PartitionIDs" + "(allocations rounded down to nearest cache block count)" + "Format: [,,...]" + "Example: [0.5, 0.75]" + ) diff --git a/src/mem/cache/tags/partitioning_policies/SConscript b/src/mem/cache/tags/partitioning_policies/SConscript new file mode 100644 index 0000000000..37c75f4de6 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/SConscript @@ -0,0 +1,51 @@ +# -*- mode:python -*- + +# Copyright (c) 2024 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. +# +# 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. + +Import('*') + +SimObject('PartitioningPolicies.py', sim_objects=[ + 'BasePartitioningPolicy', + 'MaxCapacityPartitioningPolicy', + 'WayPolicyAllocation', + 'WayPartitioningPolicy'] + ) + +Source('base_pp.cc') +Source('max_capacity_pp.cc') +Source('way_allocation.cc') +Source('way_pp.cc') +Source('partition_fields_extension.cc') diff --git a/src/mem/cache/tags/partitioning_policies/base_pp.cc b/src/mem/cache/tags/partitioning_policies/base_pp.cc new file mode 100644 index 0000000000..45e67416a2 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/base_pp.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 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. + * + * 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/tags/partitioning_policies/base_pp.hh" + +#include "params/BasePartitioningPolicy.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +BasePartitioningPolicy::BasePartitioningPolicy + (const BasePartitioningPolicyParams ¶ms): SimObject(params) +{ + +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/base_pp.hh b/src/mem/cache/tags/partitioning_policies/base_pp.hh new file mode 100644 index 0000000000..781e2af7d9 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/base_pp.hh @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 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. + * + * 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. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_BASE_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_BASE_HH__ + +#include + +#include "params/BasePartitioningPolicy.hh" +#include "sim/sim_object.hh" + +namespace gem5 +{ + +class ReplaceableEntry; + +namespace partitioning_policy +{ + +/** + * A Partitioning Policy is a cache partitioning mechanism that limits the + * cache block allocations in a cache based on a PartitionID identifier. This + * identifier may be set to any upstream memory request by attaching a + * PartitionFieldExtention to it as so: + * + * std::shared_ptr ext(PartitionFieldExtention); + * ext->setPartitionID(PartitionID); + * req->setExtension(ext); + * + * When partitioning policies are in place, the allocatable cache blocks for + * this memory request will be filtered based on its PartitionID. + * + */ +class BasePartitioningPolicy : public SimObject +{ + public: + BasePartitioningPolicy(const BasePartitioningPolicyParams ¶ms); + + /** + * Filters the allocatable cache blocks for a memory request based on its + * PartitionID and policy allocation + * @param entries candidate cache blocks for this request; filtered in place + * @param partition_id PartitionID of the upstream memory request + */ + virtual void + filterByPartition(std::vector &entries, + const uint64_t partition_id) const = 0; + + /** + * Notify of acquisition of ownership of a cache line + * @param partition_id PartitionID of the upstream memory request + */ + virtual void + notifyAcquire(const uint64_t partition_id) = 0; + + /** + * Notify of release of ownership of a cache line + * @param partition_id PartitionID of the upstream memory request + */ + virtual void + notifyRelease(const uint64_t partition_id) = 0; +}; + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_POLICIES_BASE_HH__ diff --git a/src/mem/cache/tags/partitioning_policies/max_capacity_pp.cc b/src/mem/cache/tags/partitioning_policies/max_capacity_pp.cc new file mode 100644 index 0000000000..35ceb13a3b --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/max_capacity_pp.cc @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 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. + * + * 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/tags/partitioning_policies/max_capacity_pp.hh" + +#include +#include + +#include "base/logging.hh" +#include "base/trace.hh" +#include "params/MaxCapacityPartitioningPolicy.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +MaxCapacityPartitioningPolicy::MaxCapacityPartitioningPolicy + (const MaxCapacityPartitioningPolicyParams ¶ms): + BasePartitioningPolicy(params), cacheSize(params.cache_size), + blkSize(params.blk_size), partitionIDs(params.partition_ids), + capacities(params.capacities) +{ + // check if ids and capacities vectors are the same length + if (this->partitionIDs.size() != this->capacities.size()) { + fatal("MaxCapacity Partitioning Policy configuration invalid: ids and " + "capacities arrays are not equal lengths"); + } + + // calculate total cache block count to use when creating allocation maps + const uint64_t total_block_cnt = this->cacheSize / this->blkSize; + + // check allocations and create map + for (auto i = 0; i < this->partitionIDs.size(); i++) { + const uint64_t partition_id = this->partitionIDs[i]; + const double cap_frac = capacities[i]; + + // check Capacity Fraction (cap_frac) is actually a fraction in [0,1] + if (!(cap_frac >= 0 && cap_frac <= 1)) { + fatal("MaxCapacity Partitioning Policy for PartitionID %d has " + "Capacity Fraction %f outside of [0,1] range", partition_id, + cap_frac); + } + + const uint64_t allocated_block_cnt = cap_frac * total_block_cnt; + partitionIdMaxCapacity.emplace(partition_id, allocated_block_cnt); + + DPRINTF(PartitionPolicy, "Configured MaxCapacity Partitioning Policy " + "for PartitionID: %d to use portion of size %f (%d cache blocks " + "of %d total)\n", partition_id, cap_frac, allocated_block_cnt, + total_block_cnt); + + } +} + +void +MaxCapacityPartitioningPolicy::filterByPartition( + std::vector &entries, + const uint64_t id) const +{ + if (// No entries to filter + entries.empty() || + // This partition_id is not policed + partitionIdMaxCapacity.find(id) == partitionIdMaxCapacity.end() || + // This partition_id has not yet used the cache + partitionIdCurCapacity.find(id) == partitionIdCurCapacity.end() || + // The partition_id usage is below the maximum + partitionIdCurCapacity.at(id) < partitionIdMaxCapacity.at(id)) + return; + + // Limit reached, restrict allocation only to blocks owned by + // the Partition ID + entries.erase(std::remove_if(entries.begin(), entries.end(), + [id](ReplaceableEntry *entry) { + CacheBlk *blk = static_cast(entry); + return blk->getPartitionId() != id; + }), entries.end()); +} + +void +MaxCapacityPartitioningPolicy::notifyAcquire(const uint64_t partition_id) +{ + // sanity check current allocation does not exceed its configured maximum + assert(partitionIdCurCapacity[partition_id] <= + partitionIdMaxCapacity[partition_id]); + + partitionIdCurCapacity[partition_id] += 1; +} + +void +MaxCapacityPartitioningPolicy::notifyRelease(const uint64_t partition_id) +{ + // sanity check current allocation will not cause underflow + assert(partitionIdCurCapacity[partition_id] > 0); + + partitionIdCurCapacity[partition_id] -= 1; +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/max_capacity_pp.hh b/src/mem/cache/tags/partitioning_policies/max_capacity_pp.hh new file mode 100644 index 0000000000..ba4dadebe5 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/max_capacity_pp.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2024 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. + * + * 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. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_MAX_CAPACITY_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_MAX_CAPACITY_HH__ + +#include +#include + +#include "debug/PartitionPolicy.hh" +#include "mem/cache/cache_blk.hh" +#include "mem/cache/tags/partitioning_policies/base_pp.hh" +#include "params/BasePartitioningPolicy.hh" +#include "params/MaxCapacityPartitioningPolicy.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +/** + * A MaxCapacityPartitioningPolicy filters the cache blocks available to a + * memory requestor (identified via PartitionID) based on count of already + * allocated blocks. The number of cache blocks a specific memory requestor + * can have access to is determined by its provided capacities allocation in + * the [0, 1] range. This policy has no effect on requests with unregistered + * PartitionIDs. + * + * @see BasePartitioningPolicy + */ +class MaxCapacityPartitioningPolicy : public BasePartitioningPolicy +{ + public: + MaxCapacityPartitioningPolicy + (const MaxCapacityPartitioningPolicyParams ¶ms); + + void + filterByPartition(std::vector &entries, + const uint64_t partition_id) const override; + + void + notifyAcquire(const uint64_t partition_id) override; + + void + notifyRelease(const uint64_t partition_id) override; + + private: + /** + * Cache size in number of bytes + */ + const uint64_t cacheSize; + + /** + * Cache block size in number of bytes + */ + const uint64_t blkSize; + + /** + * Vector of partitionIDs the policy operates on + */ + const std::vector< uint64_t > partitionIDs; + + /** + * Vector of capacity fractions to enforce on the policied partitionIDs + */ + const std::vector< double > capacities; + + /** + * Map of PartitionIDs and maximum allocatable cache block counts; + * On evictions full partitions are prioritized. + */ + std::unordered_map< uint64_t, uint64_t > partitionIdMaxCapacity; + + /** + * Map of PartitionIDs and currently allocated blck coutns + */ + std::unordered_map< uint64_t, uint64_t > partitionIdCurCapacity; +}; + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_POLICIES_MAX_CAPACITY_HH__ diff --git a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc b/src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc new file mode 100644 index 0000000000..bbf29a00e3 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024 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. + * + * 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 "partition_fields_extension.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +std::unique_ptr +PartitionFieldExtention::clone() const +{ + return std::make_unique(*this); +} + +uint64_t +PartitionFieldExtention::getPartitionID() const +{ + return this->_partitionID; +} + +uint64_t +PartitionFieldExtention::getPartitionMonitoringID() const +{ + return this->_partitionMonitoringID; +} + +void +PartitionFieldExtention::setPartitionID(uint64_t id) +{ + this->_partitionID = id; +} + +void +PartitionFieldExtention::setPartitionMonitoringID(uint64_t id) +{ + this->_partitionMonitoringID = id; +} + +uint64_t +readPacketPartitionID (PacketPtr pkt) +{ + // get partition_id from PartitionFieldExtention + std::shared_ptr ext = + pkt->req->getExtension(); + + // use default value if extension is not set + return (ext != nullptr) ? ext->getPartitionID() : DEFAULT_PARTITION_ID; +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh b/src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh new file mode 100644 index 0000000000..b7b9dea16d --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 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. + * + * 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. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_FIELD_EXTENTION_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_FIELD_EXTENTION_HH__ + +#include "base/extensible.hh" +#include "mem/packet.hh" +#include "mem/request.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +const uint64_t DEFAULT_PARTITION_ID = 0; +const uint64_t DEFAULT_PARTITION_MONITORING_ID = 0; + +class PartitionFieldExtention : public Extension +{ + public: + std::unique_ptr clone() const override; + PartitionFieldExtention() = default; + + /** + * _partitionID getter + * @return extension Partition ID + */ + uint64_t getPartitionID() const; + + /** + * _partitionMonitoringID getter + * @return extension Partition Monitoring ID + */ + uint64_t getPartitionMonitoringID() const; + + /** + * _partitionID setter + * @param id Partition ID to set for the extension + */ + void setPartitionID(uint64_t id); + + /** + * _partitionMonitoringID setter + * @param id Partition Monitoring ID to set for the extension + */ + void setPartitionMonitoringID(uint64_t id); + + private: + uint64_t _partitionID = DEFAULT_PARTITION_ID; + uint64_t _partitionMonitoringID = DEFAULT_PARTITION_MONITORING_ID; +}; + +/** +* Helper function to retrieve PartitionID from a packet; Returns packet +* PartitionID if available or DEFAULT_PARTITION_ID if extention is not set +* @param pkt pointer to packet (PacketPtr) +* @return packet PartitionID. +*/ +uint64_t readPacketPartitionID (PacketPtr pkt); + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_POLICIES_FIELD_EXTENTION_HH__ diff --git a/src/mem/cache/tags/partitioning_policies/way_allocation.cc b/src/mem/cache/tags/partitioning_policies/way_allocation.cc new file mode 100644 index 0000000000..ebb5d89492 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/way_allocation.cc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 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. + * + * 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/tags/partitioning_policies/way_allocation.hh" + +#include "params/WayPolicyAllocation.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +WayPolicyAllocation::WayPolicyAllocation + (const WayPolicyAllocationParams ¶ms): SimObject(params), + _ways(params.ways),_partitionId(params.partition_id) +{ + +} + +std::vector< uint64_t > +WayPolicyAllocation::getWays() const +{ + return this->_ways; +} + +uint64_t +WayPolicyAllocation::getPartitionId() const +{ + return this->_partitionId; +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/way_allocation.hh b/src/mem/cache/tags/partitioning_policies/way_allocation.hh new file mode 100644 index 0000000000..b1110af50b --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/way_allocation.hh @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 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. + * + * 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. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_ALLOCATION_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_ALLOCATION_HH__ + +#include + +#include "params/WayPolicyAllocation.hh" +#include "sim/sim_object.hh" + +namespace gem5 +{ + +class ReplaceableEntry; + +namespace partitioning_policy +{ + +/** + * A WayPolicyAllocation holds a single PartitionID->Ways allocation for Way + * Partitioning Policies. + * + * @see WayPartitioningPolicy + */ +class WayPolicyAllocation : public SimObject +{ + public: + WayPolicyAllocation(const WayPolicyAllocationParams ¶ms); + + /** + * Way Policy Allocation _ways getter + * @return Allocation ways + */ + std::vector< uint64_t > getWays() const; + + /** + * Way Policy Allocation _partitionId getter + * @return Allocation Partition ID + */ + uint64_t getPartitionId() const; + + private: + /** + * Vector of ways to allocated to the PartitionID + */ + const std::vector< uint64_t > _ways; + + /** + * PartitionID on which allocation should be enforced + */ + const uint64_t _partitionId; +}; + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_ALLOCATION_HH__ diff --git a/src/mem/cache/tags/partitioning_policies/way_pp.cc b/src/mem/cache/tags/partitioning_policies/way_pp.cc new file mode 100644 index 0000000000..ab68b934ff --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/way_pp.cc @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 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. + * + * 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/tags/partitioning_policies/way_pp.hh" + +#include + +#include "base/logging.hh" +#include "base/trace.hh" +#include "params/WayPartitioningPolicy.hh" +#include "way_allocation.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +WayPartitioningPolicy::WayPartitioningPolicy + (const WayPartitioningPolicyParams ¶ms): BasePartitioningPolicy(params) +{ + // get cache associativity and check it is usable for this policy + const auto cache_assoc = params.cache_associativity; + assert(cache_assoc > 0); + + // iterate over all provided allocations + for (const auto allocation: params.allocations) { + const auto alloc_id = allocation->getPartitionId(); + + // save way allocations in policy + for (const auto way: allocation->getWays()) { + + // check if allocations are valid + fatal_if(way >= cache_assoc, "Way Partitioning Policy allocation " + "for PartitionID: %d, Way: %d cannot be fullfiled as cache " + "associativity is %d", alloc_id, way, cache_assoc); + + if (this->partitionIdWays[alloc_id].count(way) == 0) { + this->partitionIdWays[alloc_id].emplace(way); + } else { + // do not add duplicate allocation to policy and warn + warn("Duplicate Way Partitioning Policy allocation for " + "PartitionID: %d, Way: %d", + alloc_id, way); + } + } + + // report allocation of policies + DPRINTF(PartitionPolicy, "Allocated %d ways in WayPartitioningPolicy " + "for PartitionID: %d \n", allocation->getWays().size(), + alloc_id); + } +} + +void +WayPartitioningPolicy::filterByPartition( + std::vector &entries, + const uint64_t partition_id) const +{ + if (// No entries to filter + entries.empty() || + // This partition_id is not policed + partitionIdWays.find(partition_id) == partitionIdWays.end()) { + return; + } else { + const auto entries_to_remove = std::remove_if( + entries.begin(), + entries.end(), + [this, partition_id] + (ReplaceableEntry *entry) + { + return partitionIdWays.at(partition_id).find(entry->getWay()) + == partitionIdWays.at(partition_id).end(); + } + ); + + entries.erase(entries_to_remove, entries.end()); + } +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/way_pp.hh b/src/mem/cache/tags/partitioning_policies/way_pp.hh new file mode 100644 index 0000000000..ef623689a5 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/way_pp.hh @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 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. + * + * 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. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_HH__ + +#include +#include + +#include "debug/PartitionPolicy.hh" +#include "mem/cache/replacement_policies/replaceable_entry.hh" +#include "mem/cache/tags/partitioning_policies/base_pp.hh" +#include "params/WayPartitioningPolicy.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +/** + * A WayPartitioningPolicy filters the cache blocks available to a memory + * requestor (identified via PartitionID) based on the cache ways allocated to + * that requestor. This policy has no effect on requests with unregistered + * PartitionIDs. + * + * @see BasePartitioningPolicy + */ +class WayPartitioningPolicy : public BasePartitioningPolicy +{ + public: + WayPartitioningPolicy(const WayPartitioningPolicyParams ¶ms); + + void + filterByPartition(std::vector &entries, + const uint64_t partition_id) const override; + + /** + * Empty implementation as block allocations do not vary with number of + * allocated blocks for this policy + * @param partition_id PartitionID of the upstream memory request + */ + void + notifyAcquire(const uint64_t partition_id) override {}; + + /** + * Empty implementation as block allocations do not vary with number of + * allocated blocks for this policy + * @param partition_id PartitionID of the upstream memory request + */ + void + notifyRelease(const uint64_t partition_id) override {}; + + private: + /** + * Map of policied PartitionIDs and their associated cache ways + */ + std::unordered_map< uint64_t, std::unordered_set< unsigned > > + partitionIdWays; +}; + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_POLICIES_WAY_HH__ diff --git a/src/mem/cache/tags/sector_tags.cc b/src/mem/cache/tags/sector_tags.cc index 6a9ffd02ed..73eaa46703 100644 --- a/src/mem/cache/tags/sector_tags.cc +++ b/src/mem/cache/tags/sector_tags.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 ARM Limited + * + * 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) 2018, 2020 Inria * All rights reserved. * @@ -65,6 +76,9 @@ SectorTags::SectorTags(const SectorTagsParams &p) "Block size must be at least 4 and a power of 2"); fatal_if(!isPowerOf2(numBlocksPerSector), "# of blocks per sector must be non-zero and a power of 2"); + warn_if((p.partitioning_policies.size() > 0), + "Using cache partitioning policies with sector and/or compressed " + "tags is not fully tested."); } void @@ -274,12 +288,17 @@ SectorTags::findBlock(Addr addr, bool is_secure) const CacheBlk* SectorTags::findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) + std::vector& evict_blks, + const uint64_t partition_id) { // Get possible entries to be victimized - const std::vector sector_entries = + std::vector sector_entries = indexingPolicy->getPossibleEntries(addr); + // Filter entries based on PartitionID + for (auto partitioning_policy : partitioningPolicies) + partitioning_policy->filterByPartition(sector_entries, partition_id); + // Check if the sector this address belongs to has been allocated Addr tag = extractTag(addr); SectorBlk* victim_sector = nullptr; @@ -293,6 +312,12 @@ SectorTags::findVictim(Addr addr, const bool is_secure, const std::size_t size, // If the sector is not present if (victim_sector == nullptr){ + // check if partitioning policy limited allocation and if true - return + // this assumes that sector_entries would not be empty if partitioning + // policy is not in place + if (sector_entries.size() == 0){ + return nullptr; + } // Choose replacement victim from replacement candidates victim_sector = static_cast(replacementPolicy->getVictim( sector_entries)); diff --git a/src/mem/cache/tags/sector_tags.hh b/src/mem/cache/tags/sector_tags.hh index 035b085962..87ec3c1cea 100644 --- a/src/mem/cache/tags/sector_tags.hh +++ b/src/mem/cache/tags/sector_tags.hh @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 ARM Limited + * + * 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) 2018 Inria * All rights reserved. * @@ -171,11 +182,13 @@ class SectorTags : public BaseTags * @param is_secure True if the target memory space is secure. * @param size Size, in bits, of new block to allocate. * @param evict_blks Cache blocks to be evicted. + * @param partition_id Partition ID for resource management. * @return Cache block to be replaced. */ CacheBlk* findVictim(Addr addr, const bool is_secure, const std::size_t size, - std::vector& evict_blks) override; + std::vector& evict_blks, + const uint64_t partition_id) override; /** * Calculate a block's offset in a sector from the address.