mem-cache: Implement VFT tables using cache library
The frequency table is better built using the generic cache library instead of the AssociativeSet since the secure bit is not needed for this structure. Change-Id: Ie3b6442235daec7b350c608ad1380bed58f5ccf4
This commit is contained in:
15
src/mem/cache/compressors/frequent_values.cc
vendored
15
src/mem/cache/compressors/frequent_values.cc
vendored
@@ -51,8 +51,9 @@ FrequentValues::FrequentValues(const Params &p)
|
||||
codeGenerationTicks(p.code_generation_ticks),
|
||||
checkSaturation(p.check_saturation), numVFTEntries(p.vft_entries),
|
||||
numSamples(p.num_samples), takenSamples(0), phase(SAMPLING),
|
||||
VFT(p.vft_assoc, p.vft_entries, p.vft_indexing_policy,
|
||||
p.vft_replacement_policy, VFTEntry(counterBits)),
|
||||
VFT((name() + ".VFT").c_str(),
|
||||
p.vft_entries, p.vft_assoc, p.vft_replacement_policy,
|
||||
p.vft_indexing_policy, VFTEntry(counterBits)),
|
||||
codeGenerationEvent([this]{ phase = COMPRESSING; }, name())
|
||||
{
|
||||
fatal_if((numVFTEntries - 1) > mask(chunkSizeBits),
|
||||
@@ -75,7 +76,7 @@ FrequentValues::compress(const std::vector<Chunk>& chunks, Cycles& comp_lat,
|
||||
encoder::Code code;
|
||||
int length = 0;
|
||||
if (phase == COMPRESSING) {
|
||||
VFTEntry* entry = VFT.findEntry(chunk, false);
|
||||
VFTEntry* entry = VFT.findEntry(chunk);
|
||||
|
||||
// Theoretically, the code would be the index of the entry;
|
||||
// however, there is no practical need to do so, and we simply
|
||||
@@ -159,7 +160,7 @@ FrequentValues::decompress(const CompressionData* comp_data, uint64_t* data)
|
||||
// The value at the given VFT entry must match the one stored,
|
||||
// if it is not the uncompressed value
|
||||
assert((comp_chunk.code.code == uncompressedValue) ||
|
||||
VFT.findEntry(comp_chunk.value, false));
|
||||
VFT.findEntry(comp_chunk.value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ FrequentValues::sampleValues(const std::vector<uint64_t> &data,
|
||||
{
|
||||
const std::vector<Chunk> chunks = toChunks(data.data());
|
||||
for (const Chunk& chunk : chunks) {
|
||||
VFTEntry* entry = VFT.findEntry(chunk, false);
|
||||
VFTEntry* entry = VFT.findEntry(chunk);
|
||||
bool saturated = false;
|
||||
if (!is_invalidation) {
|
||||
// If a VFT hit, increase new value's counter; otherwise, insert
|
||||
@@ -187,7 +188,7 @@ FrequentValues::sampleValues(const std::vector<uint64_t> &data,
|
||||
entry = VFT.findVictim(chunk);
|
||||
assert(entry != nullptr);
|
||||
entry->value = chunk;
|
||||
VFT.insertEntry(chunk, false, entry);
|
||||
VFT.insertEntry(chunk, entry);
|
||||
} else {
|
||||
VFT.accessEntry(entry);
|
||||
}
|
||||
@@ -234,7 +235,7 @@ FrequentValues::generateCodes()
|
||||
// representing uncompressed values
|
||||
assert(uncompressed_values.size() >= 1);
|
||||
uncompressedValue = *uncompressed_values.begin();
|
||||
assert(VFT.findEntry(uncompressedValue, false) == nullptr);
|
||||
assert(VFT.findEntry(uncompressedValue) == nullptr);
|
||||
|
||||
if (useHuffmanEncoding) {
|
||||
// Populate the queue, adding each entry as a tree with one node.
|
||||
|
||||
10
src/mem/cache/compressors/frequent_values.hh
vendored
10
src/mem/cache/compressors/frequent_values.hh
vendored
@@ -34,13 +34,13 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/cache/associative_cache.hh"
|
||||
#include "base/sat_counter.hh"
|
||||
#include "base/types.hh"
|
||||
#include "mem/cache/base.hh"
|
||||
#include "mem/cache/cache_probe_arg.hh"
|
||||
#include "mem/cache/compressors/base.hh"
|
||||
#include "mem/cache/compressors/encoders/huffman.hh"
|
||||
#include "mem/cache/prefetch/associative_set.hh"
|
||||
#include "sim/eventq.hh"
|
||||
#include "sim/probe/probe.hh"
|
||||
|
||||
@@ -112,7 +112,7 @@ class FrequentValues : public Base
|
||||
enum Phase {SAMPLING, CODE_GENERATION, COMPRESSING};
|
||||
Phase phase;
|
||||
|
||||
class VFTEntry : public TaggedEntry
|
||||
class VFTEntry : public CacheEntry
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -130,14 +130,14 @@ class FrequentValues : public Base
|
||||
SatCounter32 counter;
|
||||
|
||||
VFTEntry(std::size_t num_bits)
|
||||
: TaggedEntry(), value(0), counter(num_bits)
|
||||
: CacheEntry(), value(0), counter(num_bits)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
invalidate() override
|
||||
{
|
||||
TaggedEntry::invalidate();
|
||||
CacheEntry::invalidate();
|
||||
value = 0;
|
||||
counter.reset();
|
||||
}
|
||||
@@ -147,7 +147,7 @@ class FrequentValues : public Base
|
||||
* The Value Frequency Table, a small cache that keeps track and estimates
|
||||
* the frequency distribution of values in the cache.
|
||||
*/
|
||||
AssociativeSet<VFTEntry> VFT;
|
||||
AssociativeCache<VFTEntry> VFT;
|
||||
|
||||
/**
|
||||
* A pseudo value is used as the representation of uncompressed values.
|
||||
|
||||
Reference in New Issue
Block a user