base.cc

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

CC
639
字号
/* * Copyright (c) 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 * Definition of BaseCache functions. */#include "cpu/base.hh"#include "cpu/smt.hh"#include "mem/cache/base.hh"#include "mem/cache/mshr.hh"using namespace std;BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,                                const std::string &_label,                                std::vector<Range<Addr> > filter_ranges)    : SimpleTimingPort(_name, _cache), cache(_cache),      label(_label), otherPort(NULL),      blocked(false), mustSendRetry(false), filterRanges(filter_ranges){}BaseCache::BaseCache(const Params *p)    : MemObject(p),      mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,                  MSHRQueue_WriteBuffer),      blkSize(p->block_size),      hitLatency(p->latency),      numTarget(p->tgts_per_mshr),      blocked(0),      noTargetMSHR(NULL),      missCount(p->max_miss_count),      drainEvent(NULL){}voidBaseCache::CachePort::recvStatusChange(Port::Status status){    if (status == Port::RangeChange) {        otherPort->sendStatusChange(Port::RangeChange);    }}boolBaseCache::CachePort::checkFunctional(PacketPtr pkt){    pkt->pushLabel(label);    bool done = SimpleTimingPort::checkFunctional(pkt);    pkt->popLabel();    return done;}intBaseCache::CachePort::deviceBlockSize(){    return cache->getBlockSize();}boolBaseCache::CachePort::recvRetryCommon(){    assert(waitingOnRetry);    waitingOnRetry = false;    return false;}voidBaseCache::CachePort::setBlocked(){    assert(!blocked);    DPRINTF(Cache, "Cache Blocking\n");    blocked = true;    //Clear the retry flag    mustSendRetry = false;}voidBaseCache::CachePort::clearBlocked(){    assert(blocked);    DPRINTF(Cache, "Cache Unblocking\n");    blocked = false;    if (mustSendRetry)    {        DPRINTF(Cache, "Cache Sending Retry\n");        mustSendRetry = false;        SendRetryEvent *ev = new SendRetryEvent(this, true);        // @TODO: need to find a better time (next bus cycle?)        ev->schedule(curTick + 1);    }}voidBaseCache::init(){    if (!cpuSidePort || !memSidePort)        panic("Cache not hooked up on both sides\n");    cpuSidePort->sendStatusChange(Port::RangeChange);}voidBaseCache::regStats(){    using namespace Stats;    // Hit statistics    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        hits[access_idx]            .init(maxThreadsPerCPU)            .name(name() + "." + cstr + "_hits")            .desc("number of " + cstr + " hits")            .flags(total | nozero | nonan)            ;    }// These macros make it easier to sum the right subset of commands and// to change the subset of commands that are considered "demand" vs// "non-demand"#define SUM_DEMAND(s) \    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])// should writebacks be included here?  prior code was inconsistent...#define SUM_NON_DEMAND(s) \    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])    demandHits        .name(name() + ".demand_hits")        .desc("number of demand (read+write) hits")        .flags(total)        ;    demandHits = SUM_DEMAND(hits);    overallHits        .name(name() + ".overall_hits")        .desc("number of overall hits")        .flags(total)        ;    overallHits = demandHits + SUM_NON_DEMAND(hits);    // Miss statistics    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        misses[access_idx]            .init(maxThreadsPerCPU)            .name(name() + "." + cstr + "_misses")            .desc("number of " + cstr + " misses")            .flags(total | nozero | nonan)            ;    }    demandMisses        .name(name() + ".demand_misses")        .desc("number of demand (read+write) misses")        .flags(total)        ;    demandMisses = SUM_DEMAND(misses);    overallMisses        .name(name() + ".overall_misses")        .desc("number of overall misses")        .flags(total)        ;    overallMisses = demandMisses + SUM_NON_DEMAND(misses);    // Miss latency statistics    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        missLatency[access_idx]            .init(maxThreadsPerCPU)            .name(name() + "." + cstr + "_miss_latency")            .desc("number of " + cstr + " miss cycles")            .flags(total | nozero | nonan)            ;    }    demandMissLatency        .name(name() + ".demand_miss_latency")        .desc("number of demand (read+write) miss cycles")        .flags(total)        ;    demandMissLatency = SUM_DEMAND(missLatency);    overallMissLatency        .name(name() + ".overall_miss_latency")        .desc("number of overall miss cycles")        .flags(total)        ;    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);    // access formulas    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        accesses[access_idx]            .name(name() + "." + cstr + "_accesses")            .desc("number of " + cstr + " accesses(hits+misses)")            .flags(total | nozero | nonan)            ;        accesses[access_idx] = hits[access_idx] + misses[access_idx];    }    demandAccesses        .name(name() + ".demand_accesses")        .desc("number of demand (read+write) accesses")        .flags(total)        ;    demandAccesses = demandHits + demandMisses;    overallAccesses        .name(name() + ".overall_accesses")        .desc("number of overall (read+write) accesses")        .flags(total)        ;    overallAccesses = overallHits + overallMisses;    // miss rate formulas    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        missRate[access_idx]            .name(name() + "." + cstr + "_miss_rate")            .desc("miss rate for " + cstr + " accesses")            .flags(total | nozero | nonan)            ;        missRate[access_idx] = misses[access_idx] / accesses[access_idx];    }    demandMissRate        .name(name() + ".demand_miss_rate")        .desc("miss rate for demand accesses")        .flags(total)        ;    demandMissRate = demandMisses / demandAccesses;    overallMissRate        .name(name() + ".overall_miss_rate")        .desc("miss rate for overall accesses")        .flags(total)        ;    overallMissRate = overallMisses / overallAccesses;    // miss latency formulas    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {        MemCmd cmd(access_idx);        const string &cstr = cmd.toString();        avgMissLatency[access_idx]            .name(name() + "." + cstr + "_avg_miss_latency")            .desc("average " + cstr + " miss latency")            .flags(total | nozero | nonan)            ;        avgMissLatency[access_idx] =            missLatency[access_idx] / misses[access_idx];    }    demandAvgMissLatency        .name(name() + ".demand_avg_miss_latency")        .desc("average overall miss latency")        .flags(total)        ;    demandAvgMissLatency = demandMissLatency / demandMisses;    overallAvgMissLatency        .name(name() + ".overall_avg_miss_latency")        .desc("average overall miss latency")        .flags(total)        ;    overallAvgMissLatency = overallMissLatency / overallMisses;    blocked_cycles.init(NUM_BLOCKED_CAUSES);

⌨️ 快捷键说明

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