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 + -
显示快捷键?