gem5  v22.1.0.0
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 
43 namespace gem5
44 {
45 
46 GEM5_DEPRECATED_NAMESPACE(Compressor, compression);
47 namespace compression
48 {
49 
50 template <class T>
52  : CompressionData()
53 {
54 }
55 
56 template <class T>
57 void
58 DictionaryCompressor<T>::CompData::addEntry(std::unique_ptr<Pattern> pattern)
59 {
60  // Increase size
61  setSizeBits(getSizeBits() + pattern->getSizeBits());
62 
63  // Push new entry to list
64  entries.push_back(std::move(pattern));
65 }
66 
67 template <class T>
70 {
71  dictionary.resize(dictionarySize);
72 
74 }
75 
76 template <class T>
77 void
79 {
80  // Reset number of valid entries
81  numEntries = 0;
82 
83  // Set all entries as 0
84  std::fill(dictionary.begin(), dictionary.end(), toDictionaryEntry(0));
85 }
86 
87 template <typename T>
88 std::unique_ptr<typename DictionaryCompressor<T>::CompData>
90 {
91  return std::unique_ptr<DictionaryCompressor<T>::CompData>(new CompData());
92 }
93 
94 template <typename T>
95 std::unique_ptr<typename DictionaryCompressor<T>::Pattern>
97 {
98  // Split data in bytes
99  const DictionaryEntry bytes = toDictionaryEntry(data);
100 
101  // Start as a no-match pattern. A negative match location is used so that
102  // patterns that depend on the dictionary entry don't match
103  std::unique_ptr<Pattern> pattern =
104  getPattern(bytes, toDictionaryEntry(0), -1);
105 
106  // Search for word on dictionary
107  for (std::size_t i = 0; i < numEntries; i++) {
108  // Try matching input with possible patterns
109  std::unique_ptr<Pattern> temp_pattern =
110  getPattern(bytes, dictionary[i], i);
111 
112  // Check if found pattern is better than previous
113  if (temp_pattern->getSizeBits() < pattern->getSizeBits()) {
114  pattern = std::move(temp_pattern);
115  }
116  }
117 
118  // Update stats
119  dictionaryStats.patterns[pattern->getPatternNumber()]++;
120 
121  // Push into dictionary
122  if (pattern->shouldAllocate()) {
123  addToDictionary(bytes);
124  }
125 
126  return pattern;
127 }
128 
129 template <class T>
130 std::unique_ptr<Base::CompressionData>
132 {
133  std::unique_ptr<Base::CompressionData> comp_data =
134  instantiateDictionaryCompData();
135 
136  // Reset dictionary
137  resetDictionary();
138 
139  // Compress every value sequentially
140  CompData* const comp_data_ptr = static_cast<CompData*>(comp_data.get());
141  for (const auto& value : chunks) {
142  std::unique_ptr<Pattern> pattern = compressValue(value);
143  DPRINTF(CacheComp, "Compressed %016x to %s\n", value,
144  pattern->print());
145  comp_data_ptr->addEntry(std::move(pattern));
146  }
147 
148  // Return compressed line
149  return comp_data;
150 }
151 
152 template <class T>
153 std::unique_ptr<Base::CompressionData>
155  Cycles& comp_lat, Cycles& decomp_lat)
156 {
157  // Set latencies based on the degree of parallelization, and any extra
158  // latencies due to shifting or packaging
159  comp_lat = Cycles(compExtraLatency +
160  (chunks.size() / compChunksPerCycle));
161  decomp_lat = Cycles(decompExtraLatency +
162  (chunks.size() / decompChunksPerCycle));
163 
164  return compress(chunks);
165 }
166 
167 template <class T>
168 T
170 {
171  // Search for matching entry
172  auto entry_it = dictionary.begin();
173  std::advance(entry_it, pattern->getMatchLocation());
174 
175  // Decompress the match. If the decompressed value must be added to
176  // the dictionary, do it
177  const DictionaryEntry data = pattern->decompress(*entry_it);
178  if (pattern->shouldAllocate()) {
179  addToDictionary(data);
180  }
181 
182  // Return value
183  return fromDictionaryEntry(data);
184 }
185 
186 template <class T>
187 void
189  uint64_t* data)
190 {
191  const CompData* casted_comp_data = static_cast<const CompData*>(comp_data);
192 
193  // Reset dictionary
194  resetDictionary();
195 
196  // Decompress every entry sequentially
197  std::vector<T> decomp_values;
198  for (const auto& entry : casted_comp_data->entries) {
199  const T value = decompressValue(&*entry);
200  decomp_values.push_back(value);
201  DPRINTF(CacheComp, "Decompressed %s to %x\n", entry->print(), value);
202  }
203 
204  // Concatenate the decompressed values to generate the original data
205  for (std::size_t i = 0; i < blkSize/8; i++) {
206  data[i] = 0;
207  const std::size_t values_per_entry = sizeof(uint64_t)/sizeof(T);
208  for (int j = values_per_entry - 1; j >= 0; j--) {
209  data[i] |=
210  static_cast<uint64_t>(decomp_values[values_per_entry*i+j]) <<
211  (j*8*sizeof(T));
212  }
213  }
214 }
215 
216 template <class T>
219 {
221  for (int i = 0; i < sizeof(T); i++) {
222  entry[i] = value & 0xFF;
223  value >>= 8;
224  }
225  return entry;
226 }
227 
228 template <class T>
229 T
231 {
232  T value = 0;
233  for (int i = sizeof(T) - 1; i >= 0; i--) {
234  value <<= 8;
235  value |= entry[i];
236  }
237  return value;
238 }
239 
240 } // namespace compression
241 } // namespace gem5
242 
243 #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_IMPL_HH__
#define DPRINTF(x,...)
Definition: trace.hh:186
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.
BaseCacheCompressorParams Params
Definition: base.hh:202
static void setSizeBits(CacheBlk *blk, const std::size_t size_bits)
Set the size of the compressed block, in bits.
Definition: base.cc:225
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.
Definition of a dictionary based cache compressor.
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 24 > j
Definition: misc_types.hh:57
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)

Generated on Wed Dec 21 2022 10:22:36 for gem5 by doxygen 1.9.1