gem5 v24.0.0.0
Loading...
Searching...
No Matches
dictionary_compressor_impl.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018-2020 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
33#ifndef __MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_IMPL_HH__
34#define __MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_IMPL_HH__
35
36#include <algorithm>
37
38#include "base/trace.hh"
39#include "debug/CacheComp.hh"
41#include "params/BaseDictionaryCompressor.hh"
42
43namespace gem5
44{
45
46namespace compression
47{
48
49template <class T>
54
55template <class T>
56void
57DictionaryCompressor<T>::CompData::addEntry(std::unique_ptr<Pattern> pattern)
58{
59 // Increase size
60 setSizeBits(getSizeBits() + pattern->getSizeBits());
61
62 // Push new entry to list
63 entries.push_back(std::move(pattern));
64}
65
66template <class T>
74
75template <class T>
76void
78{
79 // Reset number of valid entries
80 numEntries = 0;
81
82 // Set all entries as 0
83 std::fill(dictionary.begin(), dictionary.end(), toDictionaryEntry(0));
84}
85
86template <typename T>
87std::unique_ptr<typename DictionaryCompressor<T>::CompData>
89{
90 return std::unique_ptr<DictionaryCompressor<T>::CompData>(new CompData());
91}
92
93template <typename T>
94std::unique_ptr<typename DictionaryCompressor<T>::Pattern>
96{
97 // Split data in bytes
98 const DictionaryEntry bytes = toDictionaryEntry(data);
99
100 // Start as a no-match pattern. A negative match location is used so that
101 // patterns that depend on the dictionary entry don't match
102 std::unique_ptr<Pattern> pattern =
103 getPattern(bytes, toDictionaryEntry(0), -1);
104
105 // Search for word on dictionary
106 for (std::size_t i = 0; i < numEntries; i++) {
107 // Try matching input with possible patterns
108 std::unique_ptr<Pattern> temp_pattern =
109 getPattern(bytes, dictionary[i], i);
110
111 // Check if found pattern is better than previous
112 if (temp_pattern->getSizeBits() < pattern->getSizeBits()) {
113 pattern = std::move(temp_pattern);
114 }
115 }
116
117 // Update stats
118 dictionaryStats.patterns[pattern->getPatternNumber()]++;
119
120 // Push into dictionary
121 if (pattern->shouldAllocate()) {
122 addToDictionary(bytes);
123 }
124
125 return pattern;
126}
127
128template <class T>
129std::unique_ptr<Base::CompressionData>
131{
132 std::unique_ptr<Base::CompressionData> comp_data =
133 instantiateDictionaryCompData();
134
135 // Reset dictionary
136 resetDictionary();
137
138 // Compress every value sequentially
139 CompData* const comp_data_ptr = static_cast<CompData*>(comp_data.get());
140 for (const auto& value : chunks) {
141 std::unique_ptr<Pattern> pattern = compressValue(value);
142 DPRINTF(CacheComp, "Compressed %016x to %s\n", value,
143 pattern->print());
144 comp_data_ptr->addEntry(std::move(pattern));
145 }
146
147 // Return compressed line
148 return comp_data;
149}
150
151template <class T>
152std::unique_ptr<Base::CompressionData>
154 Cycles& comp_lat, Cycles& decomp_lat)
155{
156 // Set latencies based on the degree of parallelization, and any extra
157 // latencies due to shifting or packaging
158 comp_lat = Cycles(compExtraLatency +
159 (chunks.size() / compChunksPerCycle));
160 decomp_lat = Cycles(decompExtraLatency +
161 (chunks.size() / decompChunksPerCycle));
162
163 return compress(chunks);
164}
165
166template <class T>
167T
169{
170 // Search for matching entry
171 auto entry_it = dictionary.begin();
172 std::advance(entry_it, pattern->getMatchLocation());
173
174 // Decompress the match. If the decompressed value must be added to
175 // the dictionary, do it
176 const DictionaryEntry data = pattern->decompress(*entry_it);
177 if (pattern->shouldAllocate()) {
178 addToDictionary(data);
179 }
180
181 // Return value
182 return fromDictionaryEntry(data);
183}
184
185template <class T>
186void
188 uint64_t* data)
189{
190 const CompData* casted_comp_data = static_cast<const CompData*>(comp_data);
191
192 // Reset dictionary
193 resetDictionary();
194
195 // Decompress every entry sequentially
196 std::vector<T> decomp_values;
197 for (const auto& entry : casted_comp_data->entries) {
198 const T value = decompressValue(&*entry);
199 decomp_values.push_back(value);
200 DPRINTF(CacheComp, "Decompressed %s to %x\n", entry->print(), value);
201 }
202
203 // Concatenate the decompressed values to generate the original data
204 for (std::size_t i = 0; i < blkSize/8; i++) {
205 data[i] = 0;
206 const std::size_t values_per_entry = sizeof(uint64_t)/sizeof(T);
207 for (int j = values_per_entry - 1; j >= 0; j--) {
208 data[i] |=
209 static_cast<uint64_t>(decomp_values[values_per_entry*i+j]) <<
210 (j*8*sizeof(T));
212 }
213}
214
215template <class T>
218{
220 for (int i = 0; i < sizeof(T); i++) {
221 entry[i] = value & 0xFF;
222 value >>= 8;
223 }
224 return entry;
225}
226
227template <class T>
228T
230{
231 T value = 0;
232 for (int i = sizeof(T) - 1; i >= 0; i--) {
233 value <<= 8;
234 value |= entry[i];
235 }
236 return value;
238
239} // namespace compression
240} // namespace gem5
241
242#endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_IMPL_HH__
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
const std::size_t dictionarySize
Dictionary size.
static void setSizeBits(CacheBlk *blk, const std::size_t size_bits)
Set the size of the compressed block, in bits.
Definition base.cc:224
virtual void addEntry(std::unique_ptr< Pattern >)
Add a pattern entry to the list of patterns.
std::vector< std::unique_ptr< Pattern > > entries
The patterns matched in the original line.
The compressed data is composed of multiple pattern entries.
virtual DictionaryEntry decompress(const DictionaryEntry dict_bytes) const =0
Decompress the pattern.
bool shouldAllocate() const
Determine if pattern allocates a dictionary entry.
uint8_t getMatchLocation() const
Get the index of the dictionary match location.
static T fromDictionaryEntry(const DictionaryEntry &entry)
Turn a dictionary entry into a value.
std::vector< DictionaryEntry > dictionary
The dictionary.
virtual void resetDictionary()
Clear all dictionary entries.
std::unique_ptr< Pattern > compressValue(const T data)
Compress data.
virtual std::unique_ptr< DictionaryCompressor::CompData > instantiateDictionaryCompData() const
Instantiate a compression data of the sub-class compressor.
std::array< uint8_t, sizeof(T)> DictionaryEntry
Convenience typedef for a dictionary entry.
T decompressValue(const Pattern *pattern)
Decompress a pattern into a value that fits in a dictionary entry.
void decompress(const CompressionData *comp_data, uint64_t *data) override
Apply the decompression process to the compressed data.
std::unique_ptr< Base::CompressionData > compress(const std::vector< Chunk > &chunks)
Apply compression.
static DictionaryEntry toDictionaryEntry(T value)
Turn a value into a dictionary entry.
STL vector class.
Definition stl.hh:37
Definition of a dictionary based cache compressor.
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36

Generated on Tue Jun 18 2024 16:24:04 for gem5 by doxygen 1.11.0