diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py index 853be2343a..fdc1d8fc0f 100644 --- a/src/mem/cache/Cache.py +++ b/src/mem/cache/Cache.py @@ -111,12 +111,6 @@ 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", - ) partitioning_manager = Param.PartitionManager( NULL, "Cache partitioning manager" ) diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py index 17df7f4780..4c159f8e20 100644 --- a/src/mem/cache/tags/Tags.py +++ b/src/mem/cache/tags/Tags.py @@ -75,10 +75,6 @@ class BaseTags(ClockedObject): SetAssociative(), "Indexing policy" ) - partitioning_policies = VectorParam.BasePartitioningPolicy( - Parent.partitioning_policies, "Partitioning policies" - ) - partitioning_manager = Param.PartitionManager( Parent.partitioning_manager, "Cache partitioning manager" ) diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc index efd72eeb9f..ca6284cf34 100644 --- a/src/mem/cache/tags/base.cc +++ b/src/mem/cache/tags/base.cc @@ -63,7 +63,6 @@ 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), partitionManager(p.partitioning_manager), warmupBound((p.warmup_percentage/100.0) * (p.size / p.block_size)), warmedUp(false), numBlocks(p.size / p.block_size), diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh index ba121db2f6..d700418937 100644 --- a/src/mem/cache/tags/base.hh +++ b/src/mem/cache/tags/base.hh @@ -56,7 +56,6 @@ #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" @@ -89,10 +88,6 @@ class BaseTags : public ClockedObject /** Indexing policy */ BaseIndexingPolicy *indexingPolicy; - /** Partitioning policies */ - std::vector - partitioningPolicies; - /** Partitioning manager */ partitioning_policy::PartitionManager *partitionManager; diff --git a/src/mem/cache/tags/base_set_assoc.cc b/src/mem/cache/tags/base_set_assoc.cc index 1973967d1b..79bcb1eff5 100644 --- a/src/mem/cache/tags/base_set_assoc.cc +++ b/src/mem/cache/tags/base_set_assoc.cc @@ -89,8 +89,9 @@ void BaseSetAssoc::invalidate(CacheBlk *blk) { // Notify partitioning policies of release of ownership - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->notifyRelease(blk->getPartitionId()); + if (partitionManager) { + partitionManager->notifyRelease(blk->getPartitionId()); + } BaseTags::invalidate(blk); diff --git a/src/mem/cache/tags/base_set_assoc.hh b/src/mem/cache/tags/base_set_assoc.hh index 18fecde199..b68238e449 100644 --- a/src/mem/cache/tags/base_set_assoc.hh +++ b/src/mem/cache/tags/base_set_assoc.hh @@ -177,8 +177,9 @@ class BaseSetAssoc : public BaseTags indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->filterByPartition(entries, partition_id); + if (partitionManager) { + partitionManager->filterByPartition(entries, partition_id); + } // Choose replacement victim from replacement candidates CacheBlk* victim = entries.empty() ? nullptr : @@ -204,13 +205,9 @@ 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 - assert(partitionManager); - const auto partitionId = - partitionManager->readPacketPartitionID(pkt); - partitioning_policy->notifyAcquire(partitionId); + if (partitionManager) { + auto partition_id = partitionManager->readPacketPartitionID(pkt); + partitionManager->notifyAcquire(partition_id); } // Update replacement policy diff --git a/src/mem/cache/tags/compressed_tags.cc b/src/mem/cache/tags/compressed_tags.cc index 96afd635aa..352ac8a3ad 100644 --- a/src/mem/cache/tags/compressed_tags.cc +++ b/src/mem/cache/tags/compressed_tags.cc @@ -50,6 +50,7 @@ #include "mem/cache/replacement_policies/base.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" #include "mem/packet.hh" #include "params/CompressedTags.hh" @@ -124,8 +125,8 @@ CompressedTags::findVictim(Addr addr, const bool is_secure, indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies){ - partitioning_policy->filterByPartition(superblock_entries, + if (partitionManager){ + partitionManager->filterByPartition(superblock_entries, partition_id); } diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index 1937ec2b25..626f419015 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -75,7 +75,7 @@ FALRU::FALRU(const Params &p) blkSize); if (!isPowerOf2(size)) fatal("Cache Size must be power of 2 for now"); - if (this->partitioningPolicies.size() != 0) + if (partitionManager) fatal("Cannot use Cache Partitioning Policies with FALRU"); blks = new FALRUBlk[numBlocks]; diff --git a/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py index fbc5a39458..a441813f8c 100644 --- a/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py +++ b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py @@ -46,6 +46,13 @@ class PartitionManager(SimObject): cxx_header = "mem/cache/tags/partitioning_policies/partition_manager.hh" cxx_class = "gem5::partitioning_policy::PartitionManager" + partitioning_policies = VectorParam.BasePartitioningPolicy( + [], + "Partitioning policies " + "Setting multiple policies will enforce all of them individually " + "in order", + ) + class BasePartitioningPolicy(SimObject): type = "BasePartitioningPolicy" diff --git a/src/mem/cache/tags/partitioning_policies/SConscript b/src/mem/cache/tags/partitioning_policies/SConscript index c79cbce71e..8ff548d535 100644 --- a/src/mem/cache/tags/partitioning_policies/SConscript +++ b/src/mem/cache/tags/partitioning_policies/SConscript @@ -50,3 +50,4 @@ Source('max_capacity_pp.cc') Source('way_allocation.cc') Source('way_pp.cc') Source('partition_fields_extension.cc') +Source('partition_manager.cc') diff --git a/src/mem/cache/tags/partitioning_policies/partition_manager.cc b/src/mem/cache/tags/partitioning_policies/partition_manager.cc new file mode 100644 index 0000000000..109a43bba7 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/partition_manager.cc @@ -0,0 +1,85 @@ +/* + * 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/partition_manager.hh" + +#include "mem/cache/tags/partitioning_policies/base_pp.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +PartitionManager::PartitionManager(const Params &p) + : SimObject(p), + partitioningPolicies(p.partitioning_policies) +{} + +void +PartitionManager::notifyAcquire(uint64_t partition_id) +{ + // Notify partitioning policies of acquisition of ownership + for (auto & partitioning_policy : partitioningPolicies) { + // get partitionId from Packet + partitioning_policy->notifyAcquire(partition_id); + } +} + +void +PartitionManager::notifyRelease(uint64_t partition_id) +{ + // Notify partitioning policies of release of ownership + for (auto partitioning_policy : partitioningPolicies) { + partitioning_policy->notifyRelease(partition_id); + } +} + +void +PartitionManager::filterByPartition( + std::vector &entries, + const uint64_t partition_id) const +{ + // Filter entries based on PartitionID + for (auto partitioning_policy : partitioningPolicies) { + partitioning_policy->filterByPartition(entries, partition_id); + } +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/partition_manager.hh b/src/mem/cache/tags/partitioning_policies/partition_manager.hh index 968d5705d8..ca9436a2cf 100644 --- a/src/mem/cache/tags/partitioning_policies/partition_manager.hh +++ b/src/mem/cache/tags/partitioning_policies/partition_manager.hh @@ -45,16 +45,18 @@ namespace gem5 { +class ReplaceableEntry; + namespace partitioning_policy { +class BasePartitioningPolicy; + class PartitionManager : public SimObject { public: PARAMS(PartitionManager); - PartitionManager(const Params &p) - : SimObject(p) - {} + PartitionManager(const Params &p); /** * PartitionManager interface to retrieve PartitionID from a packet; @@ -68,6 +70,22 @@ class PartitionManager : public SimObject { return 0; }; + + /** + * Notify of acquisition of ownership of a cache line + * @param partition_id PartitionID of the upstream memory request + */ + void notifyAcquire(uint64_t partition_id); + + void notifyRelease(uint64_t partition_id); + + void filterByPartition(std::vector &entries, + const uint64_t partition_id) const; + + protected: + /** Partitioning policies */ + std::vector + partitioningPolicies; }; } // namespace partitioning_policy diff --git a/src/mem/cache/tags/sector_tags.cc b/src/mem/cache/tags/sector_tags.cc index 73eaa46703..4f0b39286c 100644 --- a/src/mem/cache/tags/sector_tags.cc +++ b/src/mem/cache/tags/sector_tags.cc @@ -55,6 +55,7 @@ #include "mem/cache/replacement_policies/base.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" namespace gem5 { @@ -76,7 +77,7 @@ 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), + warn_if(partitionManager, "Using cache partitioning policies with sector and/or compressed " "tags is not fully tested."); } @@ -296,8 +297,8 @@ SectorTags::findVictim(Addr addr, const bool is_secure, const std::size_t size, indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->filterByPartition(sector_entries, partition_id); + if (partitionManager) + partitionManager->filterByPartition(sector_entries, partition_id); // Check if the sector this address belongs to has been allocated Addr tag = extractTag(addr);