gem5  v20.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 Compressor {
44 
45 template <class T>
47  : CompressionData()
48 {
49 }
50 
51 template <class T>
52 void
53 DictionaryCompressor<T>::CompData::addEntry(std::unique_ptr<Pattern> pattern)
54 {
55  // Increase size
56  setSizeBits(getSizeBits() + pattern->getSizeBits());
57 
58  // Push new entry to list
59  entries.push_back(std::move(pattern));
60 }
61 
62 template <class T>
65 {
66  dictionary.resize(dictionarySize);
67 
68  resetDictionary();
69 }
70 
71 template <class T>
72 void
74 {
75  // Reset number of valid entries
76  numEntries = 0;
77 
78  // Set all entries as 0
79  std::fill(dictionary.begin(), dictionary.end(), toDictionaryEntry(0));
80 }
81 
82 template <typename T>
83 std::unique_ptr<typename DictionaryCompressor<T>::CompData>
85 {
86  return std::unique_ptr<DictionaryCompressor<T>::CompData>(new CompData());
87 }
88 
89 template <typename T>
90 std::unique_ptr<typename DictionaryCompressor<T>::Pattern>
92 {
93  // Split data in bytes
94  const DictionaryEntry bytes = toDictionaryEntry(data);
95 
96  // Start as a no-match pattern. A negative match location is used so that
97  // patterns that depend on the dictionary entry don't match
98  std::unique_ptr<Pattern> pattern =
99  getPattern(bytes, toDictionaryEntry(0), -1);
100 
101  // Search for word on dictionary
102  for (std::size_t i = 0; i < numEntries; i++) {
103  // Try matching input with possible patterns
104  std::unique_ptr<Pattern> temp_pattern =
105  getPattern(bytes, dictionary[i], i);
106 
107  // Check if found pattern is better than previous
108  if (temp_pattern->getSizeBits() < pattern->getSizeBits()) {
109  pattern = std::move(temp_pattern);
110  }
111  }
112 
113  // Update stats
114  dictionaryStats.patterns[pattern->getPatternNumber()]++;
115 
116  // Push into dictionary
117  if (pattern->shouldAllocate()) {
118  addToDictionary(bytes);
119  }
120 
121  return pattern;
122 }
123 
124 template <class T>
125 std::unique_ptr<Base::CompressionData>
127 {
128  std::unique_ptr<Base::CompressionData> comp_data =
129  instantiateDictionaryCompData();
130 
131  // Reset dictionary
132  resetDictionary();
133 
134  // Compress every value sequentially
135  CompData* const comp_data_ptr = static_cast<CompData*>(comp_data.get());
136  for (const auto& value : chunks) {
137  std::unique_ptr<Pattern> pattern = compressValue(value);
138  DPRINTF(CacheComp, "Compressed %016x to %s\n", value,
139  pattern->print());
140  comp_data_ptr->addEntry(std::move(pattern));
141  }
142 
143  // Return compressed line
144  return comp_data;
145 }
146 
147 template <class T>
148 T
150 {
151  // Search for matching entry
152  auto entry_it = dictionary.begin();
153  std::advance(entry_it, pattern->getMatchLocation());
154 
155  // Decompress the match. If the decompressed value must be added to
156  // the dictionary, do it
157  const DictionaryEntry data = pattern->decompress(*entry_it);
158  if (pattern->shouldAllocate()) {
159  addToDictionary(data);
160  }
161 
162  // Return value
163  return fromDictionaryEntry(data);
164 }
165 
166 template <class T>
167 void
169  uint64_t* data)
170 {
171  const CompData* casted_comp_data = static_cast<const CompData*>(comp_data);
172 
173  // Reset dictionary
174  resetDictionary();
175 
176  // Decompress every entry sequentially
177  std::vector<T> decomp_values;
178  for (const auto& entry : casted_comp_data->entries) {
179  const T value = decompressValue(&*entry);
180  decomp_values.push_back(value);
181  DPRINTF(CacheComp, "Decompressed %s to %x\n", entry->print(), value);
182  }
183 
184  // Concatenate the decompressed values to generate the original data
185  for (std::size_t i = 0; i < blkSize/8; i++) {
186  data[i] = 0;
187  const std::size_t values_per_entry = sizeof(uint64_t)/sizeof(T);
188  for (int j = values_per_entry - 1; j >= 0; j--) {
189  data[i] |=
190  static_cast<uint64_t>(decomp_values[values_per_entry*i+j]) <<
191  (j*8*sizeof(T));
192  }
193  }
194 }
195 
196 template <class T>
199 {
200  DictionaryEntry entry;
201  for (int i = 0; i < sizeof(T); i++) {
202  entry[i] = value & 0xFF;
203  value >>= 8;
204  }
205  return entry;
206 }
207 
208 template <class T>
209 T
211 {
212  T value = 0;
213  for (int i = sizeof(T) - 1; i >= 0; i--) {
214  value <<= 8;
215  value |= entry[i];
216  }
217  return value;
218 }
219 
220 } // namespace Compressor
221 
222 #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_IMPL_HH__
Compressor::BaseDictionaryCompressor
Definition: dictionary_compressor.hh:62
data
const char data[]
Definition: circlebuf.test.cc:42
Compressor::DictionaryCompressor::CompData::CompData
CompData()
Definition: dictionary_compressor_impl.hh:46
Compressor::DictionaryCompressor::DictionaryCompressor
DictionaryCompressor(const Params *p)
Definition: dictionary_compressor_impl.hh:63
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
Compressor
Definition: base.cc:46
Compressor::DictionaryCompressor< uint64_t >::DictionaryEntry
std::array< uint8_t, sizeof(uint64_t)> DictionaryEntry
Convenience typedef for a dictionary entry.
Definition: dictionary_compressor.hh:116
std::vector< Chunk >
dictionary_compressor.hh
ArmISA::j
Bitfield< 24 > j
Definition: miscregs_types.hh:54
Compressor::Base::CompressionData
Definition: base.hh:209
Compressor::DictionaryCompressor
A template version of the dictionary compressor that allows to choose the dictionary size.
Definition: dictionary_compressor.hh:112
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
Compressor::DictionaryCompressor::CompData::addEntry
virtual void addEntry(std::unique_ptr< Pattern >)
Add a pattern entry to the list of patterns.
Definition: dictionary_compressor_impl.hh:53
Compressor::Base::Params
BaseCacheCompressorParams Params
Definition: base.hh:168
MipsISA::fill
fill
Definition: pra_constants.hh:54
trace.hh
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Compressor::Base::setSizeBits
static void setSizeBits(CacheBlk *blk, const std::size_t size_bits)
Set the size of the compressed block, in bits.
Definition: base.cc:200

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17