38#include "debug/CacheComp.hh"
40#include "params/FrequentValuesCompressor.hh"
49 :
Base(
p), useHuffmanEncoding(
p.max_code_length != 0),
50 indexEncoder(
p.max_code_length), counterBits(
p.counter_bits),
51 codeGenerationTicks(
p.code_generation_ticks),
52 checkSaturation(
p.check_saturation), numVFTEntries(
p.vft_entries),
53 numSamples(
p.num_samples), takenSamples(0), phase(SAMPLING),
54 VFT(
p.vft_assoc,
p.vft_entries,
p.vft_indexing_policy,
55 p.vft_replacement_policy,
VFTEntry(counterBits)),
59 "There are more VFT entries than possible values.");
62std::unique_ptr<Base::CompressionData>
66 std::unique_ptr<CompData> comp_data =
67 std::unique_ptr<CompData>(
new CompData());
74 for (
const auto& chunk : chunks) {
84 const unsigned index = entry ? chunk : uncompressed_index;
90 if (
index == uncompressed_index) {
92 }
else if (code.
length > 64) {
102 code = {
index, code_size};
113 DPRINTF(CacheComp,
"Compressed %016x to %016x (Size = %d) "
114 "(Phase: %d)\n", chunk, code.
code, length,
phase);
116 comp_data->compressedValues.emplace_back(code, chunk);
122 comp_data->setSizeBits(size);
154 assert(((code.
length <= 64) &&
155 (code.
code == comp_chunk.code.code)) ||
156 (comp_chunk.code.code ==
162 VFT.findEntry(comp_chunk.value,
false));
166 decomp_chunks.push_back(comp_chunk.value);
167 DPRINTF(CacheComp,
"Decompressed %016x to %016x\n",
168 comp_chunk.code.code, comp_chunk.value);
177 bool is_invalidation)
180 for (
const Chunk& chunk : chunks) {
182 bool saturated =
false;
183 if (!is_invalidation) {
187 entry =
VFT.findVictim(chunk);
188 assert(entry !=
nullptr);
189 entry->
value = chunk;
190 VFT.insertEntry(chunk,
false, entry);
192 VFT.accessEntry(entry);
199 VFT.accessEntry(entry);
207 for (
auto& entry :
VFT) {
222 std::set<uint64_t> uncompressed_values;
224 uncompressed_values.insert(uncompressed_values.end(),
i);
227 for (
const auto& entry :
VFT) {
230 uncompressed_values.erase(entry.value);
235 assert(uncompressed_values.size() >= 1);
243 for (
const auto& entry :
VFT) {
270 if (data_update.
oldData.size() > 0) {
275 if (data_update.
newData.size() > 0) {
291 assert(
cache !=
nullptr);
Cycles is a wrapper class for representing cycle counts, i.e.
Base cache compressor interface.
const Cycles compExtraLatency
Extra latency added to compression due to packaging, shifting or other operations.
void fromChunks(const std::vector< Chunk > &chunks, uint64_t *data) const
This function re-joins the chunks to recreate the original data.
BaseCache * cache
Pointer to the parent cache.
std::vector< Chunk > toChunks(const uint64_t *data) const
This function splits the raw data into chunks, so that it can be parsed by the compressor.
const Cycles decompExtraLatency
Extra latency added to decompression due to packaging, shifting or other operations.
const Cycles compChunksPerCycle
Degree of parallelization of the compression process.
uint64_t Chunk
A chunk is a basic lexical unit.
const unsigned chunkSizeBits
Chunk size, in number of bits.
const Cycles decompChunksPerCycle
Degree of parallelization of the decompression process.
std::vector< CompressedValue > compressedValues
The values contained in the original data, after being compressed sequentially.
void notify(const DataUpdate &data_update) override
SatCounter32 counter
The ideal counter width (in bits) is determined by the maximum number of times a given value appears ...
uint64_t value
The value is stored as a 64 bit entry to accomodate for the uncompressed value.
std::vector< FrequentValuesListener * > listeners
FrequentValuesCompressorParams Params
void decompress(const CompressionData *comp_data, uint64_t *data) override
Apply the decompression process to the compressed data.
void regProbeListeners() override
Register probe listeners for this object.
void sampleValues(const std::vector< uint64_t > &data, bool is_invalidation)
Sample values from a packet, adding them to the VFT.
std::unique_ptr< Base::CompressionData > compress(const std::vector< Chunk > &chunks, Cycles &comp_lat, Cycles &decomp_lat) override
Apply the compression process to the cache line.
unsigned takenSamples
Number of samples taken so far.
void probeNotify(const DataUpdate &data_update)
Process a notification event from the ProbeListener.
FrequentValues(const Params &p)
const unsigned numVFTEntries
Maximum number of VFT entries, and thus of codewords too.
const Tick codeGenerationTicks
Ticks needed to perform the CODE_GENERATION phase.
const bool checkSaturation
Whether an action must be performed when counters saturate.
void generateCodes()
End sampling phase and start the code generation.
const unsigned numSamples
Number of samples in the sampling phase.
encoder::Huffman indexEncoder
The encoder applied to the VFT indices.
const bool useHuffmanEncoding
Whether Huffman encoding is applied to the VFT indices.
uint64_t uncompressedValue
A pseudo value is used as the representation of uncompressed values.
AssociativeSet< VFTEntry > VFT
The Value Frequency Table, a small cache that keeps track and estimates the frequency distribution of...
EventFunctionWrapper codeGenerationEvent
Event to handle finishing code generation and starting compression.
void sample(uint64_t value, uint64_t frequency)
Inserts the value-frequency pair in the tree.
Code encode(const uint64_t val) const override
The function responsible for the generation of the alternative value.
void generateCodeMaps()
Generation of the code maps.
void schedule(Event &event, Tick when)
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
bool isSaturated() const
Whether the counter has achieved its maximum value or not.
ProbeManager * getProbeManager()
Get the probe manager for this object.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
A data contents update is composed of the updated block's address, the old contents,...
std::vector< uint64_t > newData
The new data contents.
std::vector< uint64_t > oldData
The stale data contents.
unsigned length
Number of bits in the code.
uint64_t code
Only the LSB of the code are relevant.
const std::string & name()