From: Daniel R. Carvalho Date: Fri, 24 May 2019 09:33:11 +0000 (+0200) Subject: mem-cache: Add move assign and delete move constr of blk X-Git-Tag: develop-gem5-snapshot~483 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=65122a29b6d592bf63aefe833adcee41c90d2769;p=gem5.git mem-cache: Add move assign and delete move constr of blk Some cache techniques may need to move a block's metadata information into another block. This must have some limitations to avoid mistakes: - The destination entry must be invalid, otherwise the replacement policy steps would be skipped. - The source entry must be valid, otherwise there would be no point in moving their metadata contents. - The entries locations (set, way, offset...) must not be moved, since they are fixed. The same principle is applied to the location specific variables, such as the replacement pointer Why it would be used: For example, when using compression, and a block goes from uncompressed to compressed state due to an overwrite, after the tag lookup (sequential access) it can be decided whether to store the new data in the old location, or, since we might have already found the block's co- allocatable blocks, move it to co-allocate. Other examples of techniques that could use this functionality are Skewed Compressed Caches, and ZCaches. Change-Id: I96e4f8cc8c992c4b01f315251d1a75d51c28692c Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36575 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris Tested-by: kokoro --- diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index bcd5c4b1b..2d866a8cc 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -155,6 +155,39 @@ class CacheBlk : public TaggedEntry CacheBlk(const CacheBlk&) = delete; CacheBlk& operator=(const CacheBlk&) = delete; + CacheBlk(const CacheBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same, that is, an entry cannot move its + * data, just its metadata contents. + */ + virtual CacheBlk& + operator=(CacheBlk&& other) + { + // Copying an entry into a valid one would imply in skipping all + // replacement steps, so it cannot be allowed + assert(!isValid()); + assert(other.isValid()); + + insert(other.getTag(), other.isSecure()); + + if (other.wasPrefetched()) { + setPrefetched(); + } + setCoherenceBits(other.coherence); + setTaskId(other.getTaskId()); + setWhenReady(curTick()); + setRefCount(other.getRefCount()); + setSrcRequestorId(other.getSrcRequestorId()); + std::swap(lockList, other.lockList); + + other.invalidate(); + + return *this; + } virtual ~CacheBlk() {}; /** @@ -168,7 +201,7 @@ class CacheBlk : public TaggedEntry clearCoherenceBits(AllBits); setTaskId(ContextSwitchTaskId::Unknown); - whenReady = MaxTick; + setWhenReady(MaxTick); setRefCount(0); setSrcRequestorId(Request::invldRequestorId); lockList.clear(); diff --git a/src/mem/cache/tags/sector_blk.hh b/src/mem/cache/tags/sector_blk.hh index ea3c79aa9..2d649cd42 100644 --- a/src/mem/cache/tags/sector_blk.hh +++ b/src/mem/cache/tags/sector_blk.hh @@ -62,7 +62,17 @@ class SectorSubBlk : public CacheBlk SectorSubBlk() : CacheBlk(), _sectorBlk(nullptr), _sectorOffset(0) {} SectorSubBlk(const SectorSubBlk&) = delete; SectorSubBlk& operator=(const SectorSubBlk&) = delete; - ~SectorSubBlk() {}; + SectorSubBlk(SectorSubBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same, that is, an entry cannot change + * its sector block nor its offset. + */ + SectorSubBlk& operator=(SectorSubBlk&& other) = default; + ~SectorSubBlk() = default; /** * Set sector block associated to this block. diff --git a/src/mem/cache/tags/super_blk.cc b/src/mem/cache/tags/super_blk.cc index 0f570f947..a6d8afb81 100644 --- a/src/mem/cache/tags/super_blk.cc +++ b/src/mem/cache/tags/super_blk.cc @@ -41,6 +41,30 @@ CompressionBlk::CompressionBlk() { } +CacheBlk& +CompressionBlk::operator=(CacheBlk&& other) +{ + operator=(std::move(static_cast(other))); + return *this; +} + +CompressionBlk& +CompressionBlk::operator=(CompressionBlk&& other) +{ + // Copy internal variables; if moving, that means we had an expansion or + // contraction, and therefore the size is no longer valid, so it is not + // moved + setDecompressionLatency(other.getDecompressionLatency()); + if (other.isCompressed()) { + setCompressed(); + } else { + setUncompressed(); + } + + CacheBlk::operator=(std::move(other)); + return *this; +} + bool CompressionBlk::isCompressed() const { diff --git a/src/mem/cache/tags/super_blk.hh b/src/mem/cache/tags/super_blk.hh index bca32662f..d7abe1872 100644 --- a/src/mem/cache/tags/super_blk.hh +++ b/src/mem/cache/tags/super_blk.hh @@ -66,7 +66,17 @@ class CompressionBlk : public SectorSubBlk CompressionBlk(); CompressionBlk(const CompressionBlk&) = delete; CompressionBlk& operator=(const CompressionBlk&) = delete; - ~CompressionBlk() {}; + CompressionBlk(CompressionBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same. + */ + CompressionBlk& operator=(CompressionBlk&& other); + CacheBlk& operator=(CacheBlk&& other); + ~CompressionBlk() = default; /** * Check if this block holds compressed data.