2 * Copyright (c) 2018-2020 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.
30 * Definition of a basic cache compressor.
31 * A cache compressor must consist of a compression and a decompression
32 * methods. It must also be aware of the size of an uncompressed cache
36 #ifndef __MEM_CACHE_COMPRESSORS_BASE_HH__
37 #define __MEM_CACHE_COMPRESSORS_BASE_HH__
41 #include "base/statistics.hh"
42 #include "base/types.hh"
43 #include "sim/sim_object.hh"
46 struct BaseCacheCompressorParams;
48 namespace Compressor {
51 * Base cache compressor interface. Every cache compressor must implement a
52 * compression and a decompression method.
54 * Compressors usually cannot parse all data input at once. Therefore, they
55 * typically divide the input into multiple *chunks*, and parse them one at
58 class Base : public SimObject
62 * Forward declaration of compression data. Every new compressor must
63 * create a new compression data based on it.
65 class CompressionData;
69 * A chunk is a basic lexical unit. The data being compressed is received
70 * by the compressor as a raw pointer. In order to parse this data, the
71 * compressor must divide it into smaller units. Typically, state-of-the-
72 * art compressors interpret cache lines as sequential 32-bit chunks
73 * (chunks), but any size is valid.
76 typedef uint64_t Chunk;
79 * This compressor must be able to access the protected functions of
80 * its sub-compressors.
85 * Uncompressed cache line size (in bytes).
87 const std::size_t blkSize;
89 /** Chunk size, in number of bits. */
90 const unsigned chunkSizeBits;
93 * Size in bytes at which a compression is classified as bad and therefore
94 * the compressed block is restored to its uncompressed format.
96 const std::size_t sizeThreshold;
98 struct BaseStats : public Stats::Group
100 const Base& compressor;
102 BaseStats(Base& compressor);
104 void regStats() override;
106 /** Number of compressions performed. */
107 Stats::Scalar compressions;
109 /** Number of blocks that were compressed to this power of two size. */
110 Stats::Vector compressionSize;
112 /** Total compressed data size, in number of bits. */
113 Stats::Scalar compressionSizeBits;
115 /** Average data size after compression, in number of bits. */
116 Stats::Formula avgCompressionSizeBits;
118 /** Number of decompressions performed. */
119 Stats::Scalar decompressions;
123 * This function splits the raw data into chunks, so that it can be
124 * parsed by the compressor.
126 * @param data The raw pointer to the data being compressed.
127 * @return The raw data divided into a vector of sequential chunks.
129 std::vector<Chunk> toChunks(const uint64_t* data) const;
132 * This function re-joins the chunks to recreate the original data.
134 * @param chunks The raw data divided into a vector of sequential chunks.
135 * @param data The raw pointer to the data.
137 void fromChunks(const std::vector<Chunk>& chunks, uint64_t* data) const;
140 * Apply the compression process to the cache line.
141 * Returns the number of cycles used by the compressor, however it is
142 * usually covered by a good pipelined execution, and is currently ignored.
143 * The decompression latency is also returned, in order to avoid
144 * increasing simulation time and memory consumption.
146 * @param chunks The cache line to be compressed, divided into chunks.
147 * @param comp_lat Compression latency in number of cycles.
148 * @param decomp_lat Decompression latency in number of cycles.
149 * @return Cache line after compression.
151 virtual std::unique_ptr<CompressionData> compress(
152 const std::vector<Chunk>& chunks, Cycles& comp_lat,
153 Cycles& decomp_lat) = 0;
156 * Apply the decompression process to the compressed data.
158 * @param comp_data Compressed cache line.
159 * @param cache_line The cache line to be decompressed.
161 virtual void decompress(const CompressionData* comp_data,
162 uint64_t* cache_line) = 0;
165 typedef BaseCacheCompressorParams Params;
166 Base(const Params *p);
167 virtual ~Base() = default;
170 * Apply the compression process to the cache line. Ignores compression
173 * @param data The cache line to be compressed.
174 * @param comp_lat Compression latency in number of cycles.
175 * @param decomp_lat Decompression latency in number of cycles.
176 * @return Cache line after compression.
178 std::unique_ptr<CompressionData>
179 compress(const uint64_t* data, Cycles& comp_lat, Cycles& decomp_lat);
182 * Get the decompression latency if the block is compressed. Latency is 0
185 * @param blk The compressed block.
187 Cycles getDecompressionLatency(const CacheBlk* blk);
190 * Set the decompression latency of compressed block.
192 * @param blk The compressed block.
193 * @param lat The decompression latency.
195 static void setDecompressionLatency(CacheBlk* blk, const Cycles lat);
198 * Set the size of the compressed block, in bits.
200 * @param blk The compressed block.
201 * @param size_bits The block size.
203 static void setSizeBits(CacheBlk* blk, const std::size_t size_bits);
206 class Base::CompressionData
210 * Compressed cache line size (in bits).
216 * Default constructor.
221 * Virtual destructor. Without it unique_ptr will cause mem leak.
223 virtual ~CompressionData();
226 * Set compression size (in bits).
228 * @param size Compressed data size.
230 void setSizeBits(std::size_t size);
233 * Get compression size (in bits).
235 * @return Compressed data size.
237 std::size_t getSizeBits() const;
240 * Get compression size (in bytes).
242 * @return Compressed data size.
244 std::size_t getSize() const;
247 } // namespace Compressor
249 #endif //__MEM_CACHE_COMPRESSORS_BASE_HH__