iic.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 707 行 · 第 1/2 页

CC
707
字号
/* * Copyright (c) 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Erik G. Hallnor *//** * @file * Definitions of the Indirect Index Cache tagstore. */#include <algorithm>#include <string>#include <vector>#include <math.h>#include "mem/cache/base.hh"#include "mem/cache/tags/iic.hh"#include "base/intmath.hh"#include "sim/core.hh" // for curTick#include "base/trace.hh" // for DPRINTFusing namespace std;/** Track the number of accesses to each cache set. */#define PROFILE_IIC 1IIC::IIC(IIC::Params &params) :    hashSets(params.numSets), blkSize(params.blkSize), assoc(params.assoc),    hitLatency(params.hitLatency), subSize(params.subblockSize),    numSub(blkSize/subSize),    trivialSize((floorLog2(params.size/subSize)*numSub)/8),    tagShift(floorLog2(blkSize)), blkMask(blkSize - 1),    subShift(floorLog2(subSize)), subMask(numSub - 1),    hashDelay(params.hashDelay),    numBlocks(params.size/subSize),    numTags(hashSets * assoc + params.size/blkSize -1),    numSecondary(params.size/blkSize),    tagNull(numTags),    primaryBound(hashSets * assoc){    int i;    // Check parameters    if (blkSize < 4 || !isPowerOf2(blkSize)) {        fatal("Block size must be at least 4 and a power of 2");    }    if (hashSets <= 0 || !isPowerOf2(hashSets)) {        fatal("# of hashsets must be non-zero and a power of 2");    }    if (assoc <= 0) {        fatal("associativity must be greater than zero");    }    if (hitLatency <= 0) {        fatal("access latency must be greater than zero");    }    if (numSub*subSize != blkSize) {        fatal("blocksize must be evenly divisible by subblock size");    }    // debug stuff    freeSecond = numSecondary;    warmedUp = false;    warmupBound = params.size/blkSize;    // Replacement Policy Initialization    repl = params.rp;    repl->setIIC(this);    //last_miss_time = 0    // allocate data reference counters    dataReferenceCount = new int[numBlocks];    memset(dataReferenceCount, 0, numBlocks*sizeof(int));    // Allocate storage for both internal data and block fast access data.    // We allocate it as one large chunk to reduce overhead and to make    // deletion easier.    int data_index = 0;    dataStore = new uint8_t[(numBlocks + numTags) * blkSize];    dataBlks = new uint8_t*[numBlocks];    for (i = 0; i < numBlocks; ++i) {        dataBlks[i] = &dataStore[data_index];        freeDataBlock(i);        data_index += subSize;    }    assert(data_index == numBlocks * subSize);    // allocate and init tag store    tagStore = new IICTag[numTags];    int blkIndex = 0;    // allocate and init sets    sets = new IICSet[hashSets];    for (i = 0; i < hashSets; ++i) {        sets[i].assoc = assoc;        sets[i].tags = new IICTag*[assoc];        sets[i].chain_ptr = tagNull;        for (int j = 0; j < assoc; ++j) {            IICTag *tag = &tagStore[blkIndex++];            tag->chain_ptr = tagNull;            tag->data_ptr.resize(numSub);            tag->size = blkSize;            tag->trivialData = new uint8_t[trivialSize];            tag->numData = 0;            sets[i].tags[j] = tag;            tag->set = i;            tag->data = &dataStore[data_index];            data_index += blkSize;        }    }    assert(blkIndex == primaryBound);    for (i = primaryBound; i < tagNull; i++) {        tagStore[i].chain_ptr = i+1;        //setup data ptrs to subblocks        tagStore[i].data_ptr.resize(numSub);        tagStore[i].size = blkSize;        tagStore[i].trivialData = new uint8_t[trivialSize];        tagStore[i].numData = 0;        tagStore[i].set = 0;        tagStore[i].data = &dataStore[data_index];        data_index += blkSize;    }    freelist = primaryBound;}IIC::~IIC(){    delete [] dataReferenceCount;    delete [] dataStore;    delete [] tagStore;    delete [] sets;}/* register cache stats */voidIIC::regStats(const string &name){    using namespace Stats;    BaseTags::regStats(name);    hitHashDepth.init(0, 20, 1);    missHashDepth.init(0, 20, 1);    setAccess.init(0, hashSets, 1);    /** IIC Statistics */    hitHashDepth        .name(name + ".hit_hash_depth_dist")        .desc("Dist. of Hash lookup depths")        .flags(pdf)        ;    missHashDepth        .name(name + ".miss_hash_depth_dist")        .desc("Dist. of Hash lookup depths")        .flags(pdf)        ;    repl->regStats(name);    if (PROFILE_IIC)        setAccess            .name(name + ".set_access_dist")            .desc("Dist. of Accesses across sets")            .flags(pdf)            ;    missDepthTotal        .name(name + ".miss_depth_total")        .desc("Total of miss depths")        ;    hashMiss        .name(name + ".hash_miss")        .desc("Total of misses in hash table")        ;    hitDepthTotal        .name(name + ".hit_depth_total")        .desc("Total of hit depths")        ;    hashHit        .name(name + ".hash_hit")        .desc("Total of hites in hash table")        ;}// probe cache for presence of given block.boolIIC::probe(Addr addr) const{    return (findBlock(addr) != NULL);}IICTag*IIC::findBlock(Addr addr, int &lat){    Addr tag = extractTag(addr);    unsigned set = hash(addr);    int set_lat;    unsigned long chain_ptr = tagNull;    if (PROFILE_IIC)        setAccess.sample(set);    IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);    set_lat = 1;    if (tag_ptr == NULL && chain_ptr != tagNull) {        int secondary_depth;        tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);        set_lat += secondary_depth;        // set depth for statistics fix this later!!! egh        sets[set].depth = set_lat;        if (tag_ptr != NULL) {            /* need to move tag into primary table */            // need to preserve chain: fix this egh            sets[set].tags[assoc-1]->chain_ptr = tag_ptr->chain_ptr;            tagSwap(tag_ptr - tagStore, sets[set].tags[assoc-1] - tagStore);            tag_ptr = sets[set].findTag(tag, chain_ptr);            assert(tag_ptr!=NULL);        }    }    set_lat = set_lat * hashDelay + hitLatency;    if (tag_ptr != NULL) {        // IIC replacement: if this is not the first element of        //   list, reorder        sets[set].moveToHead(tag_ptr);        hitHashDepth.sample(sets[set].depth);        hashHit++;        hitDepthTotal += sets[set].depth;        tag_ptr->status |= BlkReferenced;        lat = set_lat;        if (tag_ptr->whenReady > curTick && tag_ptr->whenReady - curTick > set_lat) {            lat = tag_ptr->whenReady - curTick;        }        tag_ptr->refCount += 1;    }    else {        // fall through: cache block not found, not a hit...        missHashDepth.sample(sets[set].depth);        hashMiss++;        missDepthTotal += sets[set].depth;        lat = set_lat;    }    return tag_ptr;}IICTag*IIC::findBlock(Addr addr) const{    Addr tag = extractTag(addr);    unsigned set = hash(addr);    unsigned long chain_ptr = tagNull;    IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);    if (tag_ptr == NULL && chain_ptr != tagNull) {        int secondary_depth;        tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);    }    return tag_ptr;}IICTag*IIC::findReplacement(Addr addr, PacketList &writebacks){    DPRINTF(IIC, "Finding Replacement for %x\n", addr);    unsigned set = hash(addr);    IICTag *tag_ptr;    unsigned long *tmp_data = new unsigned long[numSub];    // Get a enough subblocks for a full cache line    for (int i = 0; i < numSub; ++i){        tmp_data[i] = getFreeDataBlock(writebacks);        assert(dataReferenceCount[tmp_data[i]]==0);    }    tag_ptr = getFreeTag(set, writebacks);    tag_ptr->set = set;    for (int i=0; i< numSub; ++i) {        tag_ptr->data_ptr[i] = tmp_data[i];        dataReferenceCount[tag_ptr->data_ptr[i]]++;    }    tag_ptr->numData = numSub;    assert(tag_ptr - tagStore < primaryBound); // make sure it is in primary    tag_ptr->chain_ptr = tagNull;    sets[set].moveToHead(tag_ptr);    delete [] tmp_data;    list<unsigned long> tag_indexes;    repl->doAdvance(tag_indexes);/*    while (!tag_indexes.empty()) {        if (!tagStore[tag_indexes.front()].isCompressed()) {            compress_blocks.push_back(&tagStore[tag_indexes.front()]);        }        tag_indexes.pop_front();    }*/    tag_ptr->re = (void*)repl->add(tag_ptr-tagStore);    return tag_ptr;}voidIIC::freeReplacementBlock(PacketList & writebacks){    IICTag *tag_ptr;    unsigned long data_ptr;    /* consult replacement policy */    tag_ptr = &tagStore[repl->getRepl()];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?