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 <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36575 Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Daniel Carvalho
parent
c03462e16c
commit
65122a29b6
35
src/mem/cache/cache_blk.hh
vendored
35
src/mem/cache/cache_blk.hh
vendored
@@ -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();
|
||||
|
||||
12
src/mem/cache/tags/sector_blk.hh
vendored
12
src/mem/cache/tags/sector_blk.hh
vendored
@@ -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.
|
||||
|
||||
24
src/mem/cache/tags/super_blk.cc
vendored
24
src/mem/cache/tags/super_blk.cc
vendored
@@ -41,6 +41,30 @@ CompressionBlk::CompressionBlk()
|
||||
{
|
||||
}
|
||||
|
||||
CacheBlk&
|
||||
CompressionBlk::operator=(CacheBlk&& other)
|
||||
{
|
||||
operator=(std::move(static_cast<CompressionBlk&&>(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
|
||||
{
|
||||
|
||||
12
src/mem/cache/tags/super_blk.hh
vendored
12
src/mem/cache/tags/super_blk.hh
vendored
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user