2 * Copyright (c) 2018 Inria
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.
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.
28 * Authors: Daniel Carvalho
32 * Definition of "Base-Delta-Immediate Compression: Practical Data Compression
33 * for On-Chip Caches".
36 #ifndef __MEM_CACHE_COMPRESSORS_BDI_HH__
37 #define __MEM_CACHE_COMPRESSORS_BDI_HH__
43 #include "base/types.hh"
44 #include "mem/cache/compressors/base.hh"
49 * Default maximum number of bases in the original BDI.
51 #define BDI_DEFAULT_MAX_NUM_BASES 2
53 class BDI : public BaseCacheCompressor
57 * Forward declaration of comp data classes.
60 class BDICompDataZeros;
62 class BDICompDataUncompressed;
63 template <class TB, class TD> class BDICompDataBaseDelta;
66 * The possible encoding values. If modified, ENCODING_NAMES must be too.
68 enum ENCODING {ZERO, REP_VALUES, BASE8_1, BASE8_2, BASE8_4, BASE4_1,
69 BASE4_2, BASE2_1, UNCOMPRESSED, NUM_ENCODINGS};
72 * The respective encoding names. They are indexed by the ENCODING enum.
73 * The values are assigned in the source file, and should be modified if
74 * ENCODING is changed.
76 static const char* ENCODING_NAMES[];
79 * If set, create multiple compressor instances for each possible
80 * combination of base and delta size. Otherwise, just create a
81 * compressor for each base size with the highest available delta
82 * size. This can be used to save area and power (having less
83 * compressors). True by default.
85 const bool useMoreCompressors;
88 * Number of qwords in a cache line.
90 const std::size_t qwordsPerCacheLine;
93 * @defgroup CompressionStats Compression specific statistics.
98 * Number of data entries that were compressed to each encoding.
100 Stats::Vector encodingStats;
107 * Check if the cache line consists of only zero values.
109 * @param data The cache line.
110 * @return True if it is a ZERO cache line.
112 bool isZeroPackable(const uint64_t* data) const;
115 * Check if the cache line consists only of same values.
117 * @param data The cache line.
118 * @return True if it is a REP_VALUES cache line.
120 bool isSameValuePackable(const uint64_t* data) const;
123 * Instantiate a BaseDelta compressor with given TB and TD, and try to
124 * compress the cache line. If the compression fails, it returns a nullptr.
125 * @sa BDICompDataBaseDelta
127 * @tparam TB Type of a base entry.
128 * @tparam TD Type of a delta entry.
129 * @param data The cache line to be compressed.
130 * @param encoding Encoding value for given TB-TD combination.
131 * @return Cache line after compression or nullptr.
133 template <class TB, class TD>
134 std::unique_ptr<BDICompData> tryCompress(const uint64_t* data,
135 const uint8_t encoding) const;
140 * @param data The cache line to be compressed.
141 * @param comp_lat Compression latency in number of cycles.
142 * @param decomp_lat Decompression latency in number of cycles.
143 * @param comp_size Compressed data size.
145 std::unique_ptr<BaseCacheCompressor::CompressionData> compress(
146 const uint64_t* data, Cycles& comp_lat, Cycles& decomp_lat) override;
151 * @param comp_data Compressed cache line.
152 * @param data The cache line to be decompressed.
153 * @return Decompression latency in number of cycles.
155 void decompress(const BaseCacheCompressor::CompressionData* comp_data,
156 uint64_t* data) override;
159 /** Convenience typedef. */
160 typedef BDIParams Params;
163 * Default constructor.
165 BDI(const Params *p);
168 * Default destructor.
173 * Register local statistics.
175 void regStats() override;
179 * Template for the BDI compression data.
181 class BDI::BDICompData : public CompressionData
188 const uint8_t _encoding;
192 * Number of bits needed for the encoding field.
194 static const std::size_t encodingBits = 4;
197 * Calculate and set compressed data size.
198 * Each BDI compressor generates compressed data with different sizes.
200 virtual void calculateCompressedSize() = 0;
204 * Default constructor.
206 * @param encoding The encoding value.
208 BDICompData(const uint8_t encoding);
211 * Default destructor.
213 virtual ~BDICompData() = default;
216 * Get and decompress data at given index.
218 * The index is given relative to 64-bit entries, therefore if the base
219 * size of the given compressed data is smaller than that, this function
220 * joins multiple base-delta entries to generate the respective 64-bit
223 * @param index The index of the compressed data.
224 * @return Decompressed data for the given index.
226 virtual uint64_t access(const int index) const = 0;
231 * @return The encoding.
233 uint8_t getEncoding() const;
238 * @return The encoding name.
240 std::string getName() const;
244 * BDI compressed data containing the ZERO encoding.
246 class BDI::BDICompDataZeros : public BDICompData
250 * Calculate compressed data size using ZERO encoding.
252 void calculateCompressedSize() override;
256 * Default constructor.
261 * Get and decompress data at given index. Must always return 0.
263 * @param index The index of the compressed data.
264 * @return Decompressed data for the given index.
266 uint64_t access(const int index) const override;
270 * BDI compressed data containing the REP_VALUES encoding.
272 class BDI::BDICompDataRep : public BDICompData
276 * The repeated value.
282 * Calculate compressed data size using REP_VALUES encoding.
284 void calculateCompressedSize() override;
288 * Default constructor.
290 * @param rep_value The repeated value.
292 BDICompDataRep(const uint64_t rep_value);
295 * Get and decompress data at given index. Must always return the same
298 * @param index The index of the compressed data.
299 * @return Decompressed data for the given index.
301 uint64_t access(const int index) const override;
305 * BDI compressed data containing the UNCOMPRESSED encoding.
307 class BDI::BDICompDataUncompressed : public BDICompData
311 * Uncompressed cache line size (in bytes).
313 const std::size_t blkSize;
316 * The compressed data is the original cache line.
318 const std::vector<uint64_t> _data;
322 * Calculate compressed data size using UNCOMPRESSED encoding.
324 void calculateCompressedSize() override;
328 * Default constructor.
330 * @param data The data on which compression was applied.
331 * @param blk_size Size of a cache line in bytes.
333 BDICompDataUncompressed(const uint64_t* data,
334 const std::size_t blk_size);
337 * Get and decompress data at given index. Must return the same
338 * value as _data[index].
340 * @param index The index of the compressed data.
341 * @return Decompressed data for the given index.
343 uint64_t access(const int index) const override;
347 * Template class for BDI compressed data containing all the BASE_DELTA
348 * encodings. TB's size must always be greater than TD's.
350 * @tparam TB Type of a base entry.
351 * @tparam TD Type of a delta entry.
353 template <class TB, class TD>
354 class BDI::BDICompDataBaseDelta : public BDICompData
358 * Maximum number of bases.
360 const std::size_t maxNumBases;
363 * Bit mask to differentiate between the bases.
365 std::vector<uint8_t> bitMask;
368 * Bases. bases[0] is 0 and is not stored in a hardware implementation.
370 std::vector<TB> bases;
373 * Array of deltas (or immediate values).
375 std::vector<TD> deltas;
378 * Add a base to the bases vector.
380 * @param base The base to be added.
381 * @return True on success, false if already used all base slots.
383 bool addBase(const TB base);
386 * Add a delta to the deltas vector.
388 * @param base_index Base to which the delta refers.
389 * @param delta The delta value.
391 void addDelta(const std::size_t base_index, const TD delta);
394 * Calculate compressed data size using number of bases, the base size and
397 void calculateCompressedSize() override;
401 * Default constructor.
403 * @param encoding The encoding value for this compressor.
404 * @param blk_size Size of a cache line in bytes.
405 * @param max_num_bases Maximum number of bases allowed to be stored.
407 BDICompDataBaseDelta(const uint8_t encoding, const std::size_t blk_size,
408 const std::size_t max_num_bases = BDI_DEFAULT_MAX_NUM_BASES);
411 * Get and decompress data at given index.
413 * @param index The index of the compressed data.
414 * @return Decompressed data for the given index.
416 uint64_t access(const int index) const override;
419 * Apply base delta compression.
421 * @param data The data on which compression was applied.
422 * @param blk_size Size of a cache line in bytes.
423 * @return True on success.
425 bool compress(const uint64_t* data, const std::size_t blk_size);
428 #endif //__MEM_CACHE_COMPRESSORS_BDI_HH__