Daniel Carvalho has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/36578 )
Change subject: mem-cache: Allow moving data contractions
......................................................................
mem-cache: Allow moving data contractions
Data contractions happen when a block passes from a less compressed
(e.g., uncompressed) to a more compressed (e.g., compressed) state.
Some compaction methods enforce that a block can only be allocated
in a location matches an exact compression factor, thus on data
contractions such blocks must be moved to another location, or
they must be padded to fake a bigger size.
For compaction methods that do not have that limitation, performance
can be improved if the contracted block is moved to co-allocate with
another existing entry, since it frees up an entry.
Change-Id: I302bc561b897f9d3ce1426331fe4b5c2df76f4b5
Signed-off-by: Daniel R. Carvalho <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36578
Reviewed-by: Nikos Nikoleris <[email protected]>
Maintainer: Nikos Nikoleris <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/mem/cache/Cache.py
M src/mem/cache/base.cc
M src/mem/cache/base.hh
3 files changed, 64 insertions(+), 16 deletions(-)
Approvals:
Nikos Nikoleris: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py
index 149f485..a99d549 100644
--- a/src/mem/cache/Cache.py
+++ b/src/mem/cache/Cache.py
@@ -105,6 +105,11 @@
compressor = Param.BaseCacheCompressor(NULL, "Cache compressor.")
replace_expansions = Param.Bool(True, "Apply replacement policy to " \
"decide which blocks should be evicted on a data expansion")
+ # When a block passes from uncompressed to compressed, it may become
+ # co-allocatable with another existing entry of the same superblock,
+ # so try move the block to co-allocate it
+ move_contractions = Param.Bool(True, "Try to co-allocate blocks that "
+ "contract")
sequential_access = Param.Bool(False,
"Whether to access tags and data sequentially")
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index b128b5c..78e3f3e 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -100,6 +100,7 @@
clusivity(p.clusivity),
isReadOnly(p.is_read_only),
replaceExpansions(p.replace_expansions),
+ moveContractions(p.move_contractions),
blocked(0),
order(0),
noTargetMSHR(nullptr),
@@ -862,15 +863,31 @@
const bool is_co_allocatable =
superblock->isCompressed(compression_blk) &&
superblock->canCoAllocate(compression_size);
- // If block was compressed, possibly co-allocated with other blocks,
and
- // cannot be co-allocated anymore, one or more blocks must be evicted
to
- // make room for the expanded block
+ // If compressed size didn't change enough to modify its
co-allocatability
+ // there is nothing to do. Otherwise we may be facing a data expansion
+ // (block passing from more compressed to less compressed state), or a
+ // data contraction (less to more).
const bool was_compressed = compression_blk->isCompressed();
+ bool is_data_expansion = false;
+ bool is_data_contraction = false;
+ string op_name = "";
if (was_compressed && !is_co_allocatable) {
+ is_data_expansion = true;
+ op_name = "expansion";
+ } else if (moveContractions && !was_compressed && is_co_allocatable) {
+ is_data_contraction = true;
+ op_name = "contraction";
+ }
+
+ // If block changed compression state, it was possibly co-allocated
with
+ // other blocks and cannot be co-allocated anymore, so one or more
blocks
+ // must be evicted to make room for the expanded/contracted block
+ std::vector<CacheBlk*> evict_blks;
+ if (is_data_expansion || is_data_contraction) {
std::vector<CacheBlk*> evict_blks;
bool victim_itself = false;
CacheBlk *victim = nullptr;
- if (replaceExpansions) {
+ if (replaceExpansions || is_data_contraction) {
victim = tags->findVictim(regenerateBlkAddr(blk),
blk->isSecure(), compression_size, evict_blks);
@@ -889,8 +906,8 @@
}
// Print victim block's information
- DPRINTF(CacheRepl, "Data expansion replacement victim: %s\n",
- victim->print());
+ DPRINTF(CacheRepl, "Data %s replacement victim: %s\n",
+ op_name, victim->print());
} else {
// If we do not move the expanded block, we must make room for
// the expansion to happen, so evict every co-allocated block
@@ -908,12 +925,10 @@
return false;
}
- // Update the number of data expansions
- stats.dataExpansions++;
- DPRINTF(CacheComp, "Data expansion: expanding [%s] from %d to %d
bits"
- "\n", blk->print(), prev_size, compression_size);
+ DPRINTF(CacheComp, "Data %s: [%s] from %d to %d bits\n",
+ op_name, blk->print(), prev_size, compression_size);
- if (!victim_itself && replaceExpansions) {
+ if (!victim_itself && (replaceExpansions || is_data_contraction)) {
// Move the block's contents to the invalid block so that it
now
// co-allocates with the other existing superblock entry
tags->moveBlock(blk, victim);
@@ -922,15 +937,27 @@
}
}
- // We always store compressed blocks when possible
- if (is_co_allocatable) {
- compression_blk->setCompressed();
- } else {
- compression_blk->setUncompressed();
+ // Update the number of data expansions/contractions
+ if (is_data_expansion) {
+ stats.dataExpansions++;
+ } else if (is_data_contraction) {
+ stats.dataContractions++;
}
+
compression_blk->setSizeBits(compression_size);
compression_blk->setDecompressionLatency(decompression_lat);
+ if (is_data_expansion || is_data_contraction) {
+ // If contracting data, for sure data is compressed. If expanding,
+ // both situations can arise. When no contraction or expansion
happens
+ // block keeps its old state
+ if (is_co_allocatable) {
+ compression_blk->setCompressed();
+ } else {
+ compression_blk->setUncompressed();
+ }
+ }
+
return true;
}
@@ -2088,6 +2115,7 @@
replacements(this, "replacements", "number of replacements"),
dataExpansions(this, "data_expansions", "number of data expansions"),
+ dataContractions(this, "data_contractions", "number of data
contractions"),
cmd(MemCmd::NUM_MEM_CMDS)
{
for (int idx = 0; idx < MemCmd::NUM_MEM_CMDS; ++idx)
@@ -2307,6 +2335,7 @@
}
dataExpansions.flags(nozero | nonan);
+ dataContractions.flags(nozero | nonan);
}
void
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 62c2953..8dad1b7 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -902,6 +902,14 @@
const bool replaceExpansions;
/**
+ * Similar to data expansions, after a block improves its compression,
+ * it may need to be moved elsewhere compatible with the new
compression
+ * factor, or, if not required by the compaction method, it may be
moved
+ * to co-allocate with an existing block and thus free an entry.
+ */
+ const bool moveContractions;
+
+ /**
* Bit vector of the blocking reasons for the access path.
* @sa #BlockedCause
*/
@@ -1074,6 +1082,12 @@
/** Number of data expansions. */
Stats::Scalar dataExpansions;
+ /**
+ * Number of data contractions (blocks that had their compression
+ * factor improved).
+ */
+ Stats::Scalar dataContractions;
+
/** Per-command statistics */
std::vector<std::unique_ptr<CacheCmdStats>> cmd;
} stats;
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/36578
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I302bc561b897f9d3ce1426331fe4b5c2df76f4b5
Gerrit-Change-Number: 36578
Gerrit-PatchSet: 4
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Nikos Nikoleris <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s