base.cc revision 13945
113942Sodanrc@yahoo.com.br/* 213942Sodanrc@yahoo.com.br * Copyright (c) 2018 Inria 313942Sodanrc@yahoo.com.br * All rights reserved. 413942Sodanrc@yahoo.com.br * 513942Sodanrc@yahoo.com.br * Redistribution and use in source and binary forms, with or without 613942Sodanrc@yahoo.com.br * modification, are permitted provided that the following conditions are 713942Sodanrc@yahoo.com.br * met: redistributions of source code must retain the above copyright 813942Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer; 913942Sodanrc@yahoo.com.br * redistributions in binary form must reproduce the above copyright 1013942Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer in the 1113942Sodanrc@yahoo.com.br * documentation and/or other materials provided with the distribution; 1213942Sodanrc@yahoo.com.br * neither the name of the copyright holders nor the names of its 1313942Sodanrc@yahoo.com.br * contributors may be used to endorse or promote products derived from 1413942Sodanrc@yahoo.com.br * this software without specific prior written permission. 1513942Sodanrc@yahoo.com.br * 1613942Sodanrc@yahoo.com.br * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713942Sodanrc@yahoo.com.br * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813942Sodanrc@yahoo.com.br * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913942Sodanrc@yahoo.com.br * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013942Sodanrc@yahoo.com.br * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113942Sodanrc@yahoo.com.br * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213942Sodanrc@yahoo.com.br * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313942Sodanrc@yahoo.com.br * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413942Sodanrc@yahoo.com.br * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513942Sodanrc@yahoo.com.br * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613942Sodanrc@yahoo.com.br * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713942Sodanrc@yahoo.com.br * 2813942Sodanrc@yahoo.com.br * Authors: Daniel Carvalho 2913942Sodanrc@yahoo.com.br */ 3013942Sodanrc@yahoo.com.br 3113942Sodanrc@yahoo.com.br/** @file 3213942Sodanrc@yahoo.com.br * Definition of a basic cache compressor. 3313942Sodanrc@yahoo.com.br */ 3413942Sodanrc@yahoo.com.br 3513942Sodanrc@yahoo.com.br#include "mem/cache/compressors/base.hh" 3613942Sodanrc@yahoo.com.br 3713942Sodanrc@yahoo.com.br#include <algorithm> 3813942Sodanrc@yahoo.com.br#include <cstdint> 3913943Sodanrc@yahoo.com.br#include <string> 4013942Sodanrc@yahoo.com.br 4113942Sodanrc@yahoo.com.br#include "debug/CacheComp.hh" 4213942Sodanrc@yahoo.com.br#include "mem/cache/tags/super_blk.hh" 4313942Sodanrc@yahoo.com.br#include "params/BaseCacheCompressor.hh" 4413942Sodanrc@yahoo.com.br 4513942Sodanrc@yahoo.com.br// Uncomment this line if debugging compression 4613942Sodanrc@yahoo.com.br//#define DEBUG_COMPRESSION 4713942Sodanrc@yahoo.com.br 4813942Sodanrc@yahoo.com.brBaseCacheCompressor::CompressionData::CompressionData() 4913942Sodanrc@yahoo.com.br : _size(0) 5013942Sodanrc@yahoo.com.br{ 5113942Sodanrc@yahoo.com.br} 5213942Sodanrc@yahoo.com.br 5313942Sodanrc@yahoo.com.brBaseCacheCompressor::CompressionData::~CompressionData() 5413942Sodanrc@yahoo.com.br{ 5513942Sodanrc@yahoo.com.br} 5613942Sodanrc@yahoo.com.br 5713942Sodanrc@yahoo.com.brvoid 5813942Sodanrc@yahoo.com.brBaseCacheCompressor::CompressionData::setSizeBits(std::size_t size) 5913942Sodanrc@yahoo.com.br{ 6013942Sodanrc@yahoo.com.br _size = size; 6113942Sodanrc@yahoo.com.br} 6213942Sodanrc@yahoo.com.br 6313942Sodanrc@yahoo.com.brstd::size_t 6413942Sodanrc@yahoo.com.brBaseCacheCompressor::CompressionData::getSizeBits() const 6513942Sodanrc@yahoo.com.br{ 6613942Sodanrc@yahoo.com.br return _size; 6713942Sodanrc@yahoo.com.br} 6813942Sodanrc@yahoo.com.br 6913942Sodanrc@yahoo.com.brstd::size_t 7013942Sodanrc@yahoo.com.brBaseCacheCompressor::CompressionData::getSize() const 7113942Sodanrc@yahoo.com.br{ 7213942Sodanrc@yahoo.com.br return std::ceil(_size/8); 7313942Sodanrc@yahoo.com.br} 7413942Sodanrc@yahoo.com.br 7513942Sodanrc@yahoo.com.brBaseCacheCompressor::BaseCacheCompressor(const Params *p) 7613942Sodanrc@yahoo.com.br : SimObject(p), blkSize(p->block_size) 7713942Sodanrc@yahoo.com.br{ 7813942Sodanrc@yahoo.com.br} 7913942Sodanrc@yahoo.com.br 8013942Sodanrc@yahoo.com.brvoid 8113942Sodanrc@yahoo.com.brBaseCacheCompressor::compress(const uint64_t* data, Cycles& comp_lat, 8213942Sodanrc@yahoo.com.br Cycles& decomp_lat, std::size_t& comp_size_bits) 8313942Sodanrc@yahoo.com.br{ 8413942Sodanrc@yahoo.com.br // Apply compression 8513942Sodanrc@yahoo.com.br std::unique_ptr<CompressionData> comp_data = 8613942Sodanrc@yahoo.com.br compress(data, comp_lat, decomp_lat); 8713942Sodanrc@yahoo.com.br 8813942Sodanrc@yahoo.com.br // If we are in debug mode apply decompression just after the compression. 8913942Sodanrc@yahoo.com.br // If the results do not match, we've got an error 9013942Sodanrc@yahoo.com.br #ifdef DEBUG_COMPRESSION 9113942Sodanrc@yahoo.com.br uint64_t decomp_data[blkSize/8]; 9213942Sodanrc@yahoo.com.br 9313942Sodanrc@yahoo.com.br // Apply decompression 9413942Sodanrc@yahoo.com.br decompress(comp_data.get(), decomp_data); 9513942Sodanrc@yahoo.com.br 9613942Sodanrc@yahoo.com.br // Check if decompressed line matches original cache line 9713942Sodanrc@yahoo.com.br fatal_if(std::memcmp(data, decomp_data, blkSize), 9813942Sodanrc@yahoo.com.br "Decompressed line does not match original line."); 9913942Sodanrc@yahoo.com.br #endif 10013942Sodanrc@yahoo.com.br 10113942Sodanrc@yahoo.com.br // Get compression size 10213942Sodanrc@yahoo.com.br comp_size_bits = comp_data->getSizeBits(); 10313942Sodanrc@yahoo.com.br 10413943Sodanrc@yahoo.com.br // Update stats 10513943Sodanrc@yahoo.com.br compressionSize[std::ceil(std::log2(comp_size_bits))]++; 10613943Sodanrc@yahoo.com.br 10713942Sodanrc@yahoo.com.br // Print debug information 10813942Sodanrc@yahoo.com.br DPRINTF(CacheComp, "Compressed cache line from %d to %d bits. " \ 10913942Sodanrc@yahoo.com.br "Compression latency: %llu, decompression latency: %llu\n", 11013942Sodanrc@yahoo.com.br blkSize*8, comp_size_bits, comp_lat, decomp_lat); 11113942Sodanrc@yahoo.com.br} 11213942Sodanrc@yahoo.com.br 11313942Sodanrc@yahoo.com.brCycles 11413945Sodanrc@yahoo.com.brBaseCacheCompressor::getDecompressionLatency(const CacheBlk* blk) const 11513942Sodanrc@yahoo.com.br{ 11613942Sodanrc@yahoo.com.br const CompressionBlk* comp_blk = static_cast<const CompressionBlk*>(blk); 11713942Sodanrc@yahoo.com.br 11813942Sodanrc@yahoo.com.br // If block is compressed, return its decompression latency 11913942Sodanrc@yahoo.com.br if (comp_blk && comp_blk->isCompressed()){ 12013945Sodanrc@yahoo.com.br const Cycles decomp_lat = comp_blk->getDecompressionLatency(); 12113945Sodanrc@yahoo.com.br DPRINTF(CacheComp, "Decompressing block: %s (%d cycles)\n", 12213945Sodanrc@yahoo.com.br comp_blk->print(), decomp_lat); 12313945Sodanrc@yahoo.com.br return decomp_lat; 12413942Sodanrc@yahoo.com.br } 12513942Sodanrc@yahoo.com.br 12613942Sodanrc@yahoo.com.br // Block is not compressed, so there is no decompression latency 12713942Sodanrc@yahoo.com.br return Cycles(0); 12813942Sodanrc@yahoo.com.br} 12913942Sodanrc@yahoo.com.br 13013942Sodanrc@yahoo.com.brvoid 13113942Sodanrc@yahoo.com.brBaseCacheCompressor::setDecompressionLatency(CacheBlk* blk, const Cycles lat) 13213942Sodanrc@yahoo.com.br{ 13313942Sodanrc@yahoo.com.br // Sanity check 13413942Sodanrc@yahoo.com.br assert(blk != nullptr); 13513942Sodanrc@yahoo.com.br 13613942Sodanrc@yahoo.com.br // Assign latency 13713942Sodanrc@yahoo.com.br static_cast<CompressionBlk*>(blk)->setDecompressionLatency(lat); 13813942Sodanrc@yahoo.com.br} 13913942Sodanrc@yahoo.com.br 14013942Sodanrc@yahoo.com.brvoid 14113942Sodanrc@yahoo.com.brBaseCacheCompressor::setSizeBits(CacheBlk* blk, const std::size_t size_bits) 14213942Sodanrc@yahoo.com.br{ 14313942Sodanrc@yahoo.com.br // Sanity check 14413942Sodanrc@yahoo.com.br assert(blk != nullptr); 14513942Sodanrc@yahoo.com.br 14613942Sodanrc@yahoo.com.br // Assign size 14713942Sodanrc@yahoo.com.br static_cast<CompressionBlk*>(blk)->setSizeBits(size_bits); 14813942Sodanrc@yahoo.com.br} 14913942Sodanrc@yahoo.com.br 15013943Sodanrc@yahoo.com.brvoid 15113943Sodanrc@yahoo.com.brBaseCacheCompressor::regStats() 15213943Sodanrc@yahoo.com.br{ 15313943Sodanrc@yahoo.com.br SimObject::regStats(); 15413943Sodanrc@yahoo.com.br 15513943Sodanrc@yahoo.com.br // We also store when compression is bigger than original block size 15613943Sodanrc@yahoo.com.br compressionSize 15713943Sodanrc@yahoo.com.br .init(std::log2(blkSize*8) + 2) 15813943Sodanrc@yahoo.com.br .name(name() + ".compression_size") 15913943Sodanrc@yahoo.com.br .desc("Number of blocks that were compressed to this power of" \ 16013943Sodanrc@yahoo.com.br "two size.") 16113943Sodanrc@yahoo.com.br ; 16213943Sodanrc@yahoo.com.br 16313943Sodanrc@yahoo.com.br for (unsigned i = 0; i <= std::log2(blkSize*8) + 1; ++i) { 16413943Sodanrc@yahoo.com.br compressionSize.subname(i, std::to_string(1 << i)); 16513943Sodanrc@yahoo.com.br compressionSize.subdesc(i, "Number of blocks that compressed to fit " \ 16613943Sodanrc@yahoo.com.br "in " + std::to_string(1 << i) + " bits"); 16713943Sodanrc@yahoo.com.br } 16813943Sodanrc@yahoo.com.br} 16913943Sodanrc@yahoo.com.br 170