inorder: init internal debug cpu counters

- cpuEventNum
- resReqCount
This commit is contained in:
Korey Sewell 2010-01-31 17:18:15 -05:00
parent ab2f864af2
commit 7b3b362ba5
4 changed files with 128 additions and 58 deletions

View file

@ -115,7 +115,8 @@ InOrderCPU::CPUEvent::process()
cpu->activateThread(tid); cpu->activateThread(tid);
break; break;
//@TODO: Consider Implementing "Suspend Thread" as Separate from Deallocate //@TODO: Consider Implementing "Suspend Thread" as Separate from
//Deallocate
case SuspendThread: // Suspend & Deallocate are same for now. case SuspendThread: // Suspend & Deallocate are same for now.
//cpu->suspendThread(tid); //cpu->suspendThread(tid);
//break; //break;
@ -145,11 +146,14 @@ InOrderCPU::CPUEvent::process()
default: default:
fatal("Unrecognized Event Type %d", cpuEventType); fatal("Unrecognized Event Type %d", cpuEventType);
} }
cpu->cpuEventRemoveList.push(this); cpu->cpuEventRemoveList.push(this);
} }
const char * const char *
InOrderCPU::CPUEvent::description() InOrderCPU::CPUEvent::description()
{ {
@ -185,6 +189,10 @@ InOrderCPU::InOrderCPU(Params *params)
system(params->system), system(params->system),
physmem(system->physmem), physmem(system->physmem),
#endif // FULL_SYSTEM #endif // FULL_SYSTEM
#ifdef DEBUG
cpuEventNum(0),
resReqCount(0),
#endif // DEBUG
switchCount(0), switchCount(0),
deferRegistration(false/*params->deferRegistration*/), deferRegistration(false/*params->deferRegistration*/),
stageTracing(params->stageTracing), stageTracing(params->stageTracing),
@ -301,7 +309,7 @@ InOrderCPU::InOrderCPU(Params *params)
// Define dummy instructions and resource requests to be used. // Define dummy instructions and resource requests to be used.
DynInstPtr dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0); DynInstPtr dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0);
dummyReq = new ResourceRequest(NULL, NULL, 0, 0, 0, 0); dummyReq = new ResourceRequest(resPool->getResource(0), NULL, 0, 0, 0, 0);
// Reset CPU to reset state. // Reset CPU to reset state.
#if FULL_SYSTEM #if FULL_SYSTEM
@ -322,6 +330,13 @@ InOrderCPU::regStats()
/* Register the Resource Pool's stats here.*/ /* Register the Resource Pool's stats here.*/
resPool->regStats(); resPool->regStats();
#ifdef DEBUG
maxResReqCount
.name(name() + ".maxResReqCount")
.desc("Maximum number of live resource requests in CPU")
.prereq(maxResReqCount);
#endif
/* Register any of the InOrderCPU's stats here.*/ /* Register any of the InOrderCPU's stats here.*/
timesIdled timesIdled
.name(name() + ".timesIdled") .name(name() + ".timesIdled")
@ -342,7 +357,7 @@ InOrderCPU::regStats()
smtCycles smtCycles
.name(name() + ".smtCycles") .name(name() + ".smtCycles")
.desc("Total number of cycles that the CPU was simultaneous multithreading.(SMT)"); .desc("Total number of cycles that the CPU was in SMT-mode");
committedInsts committedInsts
.init(numThreads) .init(numThreads)
@ -435,7 +450,8 @@ InOrderCPU::tick()
//Tick next_tick = curTick + cycles(1); //Tick next_tick = curTick + cycles(1);
//tickEvent.schedule(next_tick); //tickEvent.schedule(next_tick);
mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1)); mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1));
DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle(curTick + 1)); DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n",
nextCycle(curTick + 1));
} }
} }
@ -640,8 +656,8 @@ void
InOrderCPU::addToCurrentThreads(ThreadID tid) InOrderCPU::addToCurrentThreads(ThreadID tid)
{ {
if (!isThreadInCPU(tid)) { if (!isThreadInCPU(tid)) {
DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU.\n", DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU."
tid); "\n", tid);
currentThreads.push_back(tid); currentThreads.push_back(tid);
} }
} }
@ -1002,9 +1018,11 @@ InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
tid = TheISA::getTargetThread(tcBase(tid)); tid = TheISA::getTargetThread(tcBase(tid));
} }
if (reg_idx < FP_Base_DepTag) { // Integer Register File if (reg_idx < FP_Base_DepTag) {
// Integer Register File
return readIntReg(reg_idx, tid); return readIntReg(reg_idx, tid);
} else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File } else if (reg_idx < Ctrl_Base_DepTag) {
// Float Register File
reg_idx -= FP_Base_DepTag; reg_idx -= FP_Base_DepTag;
return readFloatRegBits(reg_idx, tid); return readFloatRegBits(reg_idx, tid);
} else { } else {
@ -1070,9 +1088,12 @@ InOrderCPU::addInst(DynInstPtr &inst)
void void
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
{ {
// Set the CPU's PCs - This contributes to the precise state of the CPU which can be used // Set the CPU's PCs - This contributes to the precise state of the CPU
// when restoring a thread to the CPU after a fork or after an exception // which can be used when restoring a thread to the CPU after a fork or
// @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if it's a branch or not // after an exception
// =================
// @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if
// it's a branch or not
setPC(inst->readPC(), tid); setPC(inst->readPC(), tid);
setNextPC(inst->readNextPC(), tid); setNextPC(inst->readNextPC(), tid);
setNextNPC(inst->readNextNPC(), tid); setNextNPC(inst->readNextNPC(), tid);
@ -1112,7 +1133,8 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
// Broadcast to other resources an instruction // Broadcast to other resources an instruction
// has been completed // has been completed
resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst, tid); resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst,
tid);
// Finally, remove instruction from CPU // Finally, remove instruction from CPU
removeInst(inst); removeInst(inst);
@ -1380,7 +1402,8 @@ InOrderCPU::read(DynInstPtr inst, Addr addr, T &data, unsigned flags)
{ {
//@TODO: Generalize name "CacheUnit" to "MemUnit" just in case //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case
// you want to run w/out caches? // you want to run w/out caches?
CacheUnit *cache_res = dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx)); CacheUnit *cache_res =
dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx));
return cache_res->read(inst, addr, data, flags); return cache_res->read(inst, addr, data, flags);
} }
@ -1483,14 +1506,16 @@ InOrderCPU::write(DynInstPtr inst, uint8_t data, Addr addr,
template<> template<>
Fault Fault
InOrderCPU::write(DynInstPtr inst, double data, Addr addr, unsigned flags, uint64_t *res) InOrderCPU::write(DynInstPtr inst, double data, Addr addr, unsigned flags,
uint64_t *res)
{ {
return write(inst, *(uint64_t*)&data, addr, flags, res); return write(inst, *(uint64_t*)&data, addr, flags, res);
} }
template<> template<>
Fault Fault
InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, uint64_t *res) InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags,
uint64_t *res)
{ {
return write(inst, *(uint32_t*)&data, addr, flags, res); return write(inst, *(uint32_t*)&data, addr, flags, res);
} }
@ -1498,7 +1523,8 @@ InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, uint64
template<> template<>
Fault Fault
InOrderCPU::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags, uint64_t *res) InOrderCPU::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags,
uint64_t *res)
{ {
return write(inst, (uint32_t)data, addr, flags, res); return write(inst, (uint32_t)data, addr, flags, res);
} }

View file

@ -144,9 +144,11 @@ class InOrderCPU : public BaseCPU
void scheduleTickEvent(int delay) void scheduleTickEvent(int delay)
{ {
if (tickEvent.squashed()) if (tickEvent.squashed())
mainEventQueue.reschedule(&tickEvent, nextCycle(curTick + ticks(delay))); mainEventQueue.reschedule(&tickEvent,
nextCycle(curTick + ticks(delay)));
else if (!tickEvent.scheduled()) else if (!tickEvent.scheduled())
mainEventQueue.schedule(&tickEvent, nextCycle(curTick + ticks(delay))); mainEventQueue.schedule(&tickEvent,
nextCycle(curTick + ticks(delay)));
} }
/** Unschedule tick event, regardless of its current state. */ /** Unschedule tick event, regardless of its current state. */
@ -228,7 +230,8 @@ class InOrderCPU : public BaseCPU
/** Interface between the CPU and CPU resources. */ /** Interface between the CPU and CPU resources. */
ResourcePool *resPool; ResourcePool *resPool;
/** Instruction used to signify that there is no *real* instruction in buffer slot */ /** Instruction used to signify that there is no *real* instruction in
buffer slot */
DynInstPtr dummyBufferInst; DynInstPtr dummyBufferInst;
/** Used by resources to signify a denied access to a resource. */ /** Used by resources to signify a denied access to a resource. */
@ -420,7 +423,11 @@ class InOrderCPU : public BaseCPU
/** Get & Update Next Event Number */ /** Get & Update Next Event Number */
InstSeqNum getNextEventNum() InstSeqNum getNextEventNum()
{ {
#ifdef DEBUG
return cpuEventNum++; return cpuEventNum++;
#else
return 0;
#endif
} }
/** Register file accessors */ /** Register file accessors */
@ -550,8 +557,8 @@ class InOrderCPU : public BaseCPU
*/ */
std::queue<ListIt> removeList; std::queue<ListIt> removeList;
/** List of all the resource requests that will be removed at the end of this /** List of all the resource requests that will be removed at the end
* cycle. * of this cycle.
*/ */
std::queue<ResourceRequest*> reqRemoveList; std::queue<ResourceRequest*> reqRemoveList;
@ -632,8 +639,12 @@ class InOrderCPU : public BaseCPU
// LL/SC debug functionality // LL/SC debug functionality
unsigned stCondFails; unsigned stCondFails;
unsigned readStCondFailures() { return stCondFails; }
unsigned setStCondFailures(unsigned st_fails) { return stCondFails = st_fails; } unsigned readStCondFailures()
{ return stCondFails; }
unsigned setStCondFailures(unsigned st_fails)
{ return stCondFails = st_fails; }
/** Returns a pointer to a thread context. */ /** Returns a pointer to a thread context. */
ThreadContext *tcBase(ThreadID tid = 0) ThreadContext *tcBase(ThreadID tid = 0)
@ -663,9 +674,16 @@ class InOrderCPU : public BaseCPU
/** The global sequence number counter. */ /** The global sequence number counter. */
InstSeqNum globalSeqNum[ThePipeline::MaxThreads]; InstSeqNum globalSeqNum[ThePipeline::MaxThreads];
#ifdef DEBUG
/** The global event number counter. */ /** The global event number counter. */
InstSeqNum cpuEventNum; InstSeqNum cpuEventNum;
/** Number of resource requests active in CPU **/
unsigned resReqCount;
Stats::Scalar maxResReqCount;
#endif
/** Counter of how many stages have completed switching out. */ /** Counter of how many stages have completed switching out. */
int switchCount; int switchCount;

View file

@ -80,7 +80,8 @@ Resource::regStats()
{ {
instReqsProcessed instReqsProcessed
.name(name() + ".instReqsProcessed") .name(name() + ".instReqsProcessed")
.desc("Number of Instructions Requests that completed in this resource."); .desc("Number of Instructions Requests that completed in "
"this resource.");
} }
int int
@ -98,7 +99,8 @@ Resource::slotsInUse()
void void
Resource::freeSlot(int slot_idx) Resource::freeSlot(int slot_idx)
{ {
DPRINTF(RefCount, "Removing [tid:%i] [sn:%i]'s request from resource [slot:%i].\n", DPRINTF(RefCount, "Removing [tid:%i] [sn:%i]'s request from resource "
"[slot:%i].\n",
reqMap[slot_idx]->inst->readTid(), reqMap[slot_idx]->inst->readTid(),
reqMap[slot_idx]->inst->seqNum, reqMap[slot_idx]->inst->seqNum,
slot_idx); slot_idx);
@ -159,7 +161,8 @@ Resource::getSlot(DynInstPtr inst)
while (map_it != map_end) { while (map_it != map_end) {
if ((*map_it).second) { if ((*map_it).second) {
DPRINTF(Resource, "Currently Serving request from: [tid:%i] [sn:%i].\n", DPRINTF(Resource, "Currently Serving request from: "
"[tid:%i] [sn:%i].\n",
(*map_it).second->getInst()->readTid(), (*map_it).second->getInst()->readTid(),
(*map_it).second->getInst()->seqNum); (*map_it).second->getInst()->seqNum);
} }
@ -202,10 +205,12 @@ Resource::request(DynInstPtr inst)
inst_req = getRequest(inst, stage_num, id, slot_num, cmd); inst_req = getRequest(inst, stage_num, id, slot_num, cmd);
if (inst->staticInst) { if (inst->staticInst) {
DPRINTF(Resource, "[tid:%i]: [sn:%i] requesting this resource.\n", DPRINTF(Resource, "[tid:%i]: [sn:%i] requesting this "
"resource.\n",
inst->readTid(), inst->seqNum); inst->readTid(), inst->seqNum);
} else { } else {
DPRINTF(Resource, "[tid:%i]: instruction requesting this resource.\n", DPRINTF(Resource, "[tid:%i]: instruction requesting this "
"resource.\n",
inst->readTid()); inst->readTid());
} }
@ -232,7 +237,8 @@ Resource::requestAgain(DynInstPtr inst, bool &do_request)
do_request = true; do_request = true;
if (inst->staticInst) { if (inst->staticInst) {
DPRINTF(Resource, "[tid:%i]: [sn:%i] requesting this resource again.\n", DPRINTF(Resource, "[tid:%i]: [sn:%i] requesting this resource "
"again.\n",
inst->readTid(), inst->seqNum); inst->readTid(), inst->seqNum);
} else { } else {
DPRINTF(Resource, "[tid:%i]: requesting this resource again.\n", DPRINTF(Resource, "[tid:%i]: requesting this resource again.\n",
@ -394,7 +400,41 @@ Resource::unscheduleEvent(DynInstPtr inst)
int ResourceRequest::resReqID = 0; int ResourceRequest::resReqID = 0;
int ResourceRequest::resReqCount = 0; int ResourceRequest::maxReqCount = 0;
ResourceRequest::ResourceRequest(Resource *_res, DynInstPtr _inst,
int stage_num, int res_idx, int slot_num,
unsigned _cmd)
: res(_res), inst(_inst), cmd(_cmd), stageNum(stage_num),
resIdx(res_idx), slotNum(slot_num), completed(false),
squashed(false), processing(false), waiting(false)
{
#ifdef DEBUG
reqID = resReqID++;
res->cpu->resReqCount++;
DPRINTF(ResReqCount, "Res. Req %i created. resReqCount=%i.\n", reqID,
res->cpu->resReqCount);
if (res->cpu->resReqCount > 100) {
fatal("Too many undeleted resource requests. Memory leak?\n");
}
if (res->cpu->resReqCount > maxReqCount) {
maxReqCount = res->cpu->resReqCount;
res->cpu->maxResReqCount = maxReqCount;
}
#endif
}
ResourceRequest::~ResourceRequest()
{
#ifdef DEBUG
res->cpu->resReqCount--;
DPRINTF(ResReqCount, "Res. Req %i deleted. resReqCount=%i.\n", reqID,
res->cpu->resReqCount);
#endif
}
void void
ResourceRequest::done(bool completed) ResourceRequest::done(bool completed)

View file

@ -70,7 +70,8 @@ class Resource {
/** Define this function if resource, has a port to connect to an outside /** Define this function if resource, has a port to connect to an outside
* simulation object. * simulation object.
*/ */
virtual Port* getPort(const std::string &if_name, int idx) { return NULL; } virtual Port* getPort(const std::string &if_name, int idx)
{ return NULL; }
/** Return ID for this resource */ /** Return ID for this resource */
int getId() { return id; } int getId() { return id; }
@ -114,9 +115,9 @@ class Resource {
/** Free a resource slot */ /** Free a resource slot */
virtual void freeSlot(int slot_idx); virtual void freeSlot(int slot_idx);
/** Request usage of a resource for this instruction. If this instruction already /** Request usage of a resource for this instruction. If this instruction
* has made this request to this resource, and that request is uncompleted * already has made this request to this resource, and that request is
* this function will just return that request * uncompleted this function will just return that request
*/ */
virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num, virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
int res_idx, int slot_num, int res_idx, int slot_num,
@ -166,7 +167,8 @@ class Resource {
/** Schedule resource event, regardless of its current state. */ /** Schedule resource event, regardless of its current state. */
void scheduleEvent(int slot_idx, int delay); void scheduleEvent(int slot_idx, int delay);
/** Find instruction in list, Schedule resource event, regardless of its current state. */ /** Find instruction in list, Schedule resource event, regardless of its
* current state. */
bool scheduleEvent(DynInstPtr inst, int delay); bool scheduleEvent(DynInstPtr inst, int delay);
/** Unschedule resource event, regardless of its current state. */ /** Unschedule resource event, regardless of its current state. */
@ -303,30 +305,14 @@ class ResourceRequest
static int resReqID; static int resReqID;
static int resReqCount; static int maxReqCount;
public: public:
ResourceRequest(Resource *_res, DynInstPtr _inst, int stage_num, ResourceRequest(Resource *_res, DynInstPtr _inst, int stage_num,
int res_idx, int slot_num, unsigned _cmd) int res_idx, int slot_num, unsigned _cmd);
: res(_res), inst(_inst), cmd(_cmd), stageNum(stage_num),
resIdx(res_idx), slotNum(slot_num), completed(false), virtual ~ResourceRequest();
squashed(false), processing(false), waiting(false)
{
reqID = resReqID++;
resReqCount++;
DPRINTF(ResReqCount, "Res. Req %i created. resReqCount=%i.\n", reqID, resReqCount);
if (resReqCount > 100) {
fatal("Too many undeleted resource requests. Memory leak?\n");
}
}
virtual ~ResourceRequest()
{
resReqCount--;
DPRINTF(ResReqCount, "Res. Req %i deleted. resReqCount=%i.\n", reqID, resReqCount);
}
int reqID; int reqID;
/** Acknowledge that this is a request is done and remove /** Acknowledge that this is a request is done and remove