From d53d04473e0d6ca1765f1117072eec59187a7f7b Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 28 Aug 2012 14:30:31 -0400 Subject: Clock: Rework clocks to avoid tick-to-cycle transformations This patch introduces the notion of a clock update function that aims to avoid costly divisions when turning the current tick into a cycle. Each clocked object advances a private (hidden) cycle member and a tick member and uses these to implement functions for getting the tick of the next cycle, or the tick of a cycle some time in the future. In the different modules using the clocks, changes are made to avoid counting in ticks only to later translate to cycles. There are a few oddities in how the O3 and inorder CPU count idle cycles, as seen by a few locations where a cycle is subtracted in the calculation. This is done such that the regression does not change any stats, but should be revisited in a future patch. Another, much needed, change that is not done as part of this patch is to introduce a new typedef uint64_t Cycle to be able to at least hint at the unit of the variables counting Ticks vs Cycles. This will be done as a follow-up patch. As an additional follow up, the thread context still uses ticks for the book keeping of last activate and last suspend and this should probably also be changed into cycles as well. --- src/cpu/inorder/cpu.cc | 31 ++++++++++++++----------------- src/cpu/inorder/cpu.hh | 2 +- src/cpu/inorder/resource.cc | 2 +- src/cpu/inorder/resource_pool.cc | 4 ++-- 4 files changed, 18 insertions(+), 21 deletions(-) (limited to 'src/cpu/inorder') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 4aff0c579..ec06f19f0 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -212,7 +212,7 @@ void InOrderCPU::CPUEvent::scheduleEvent(int delay) { assert(!scheduled() || squashed()); - cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true); + cpu->reschedule(this, cpu->clockEdge(delay), true); } void @@ -401,7 +401,7 @@ InOrderCPU::InOrderCPU(Params *params) frontEndSked = createFrontEndSked(); faultSked = createFaultSked(); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); lockAddr = 0; lockFlag = false; @@ -761,17 +761,17 @@ InOrderCPU::tick() if (!tickEvent.scheduled()) { if (_status == SwitchedOut) { // increment stat - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); } else if (!activityRec.active()) { DPRINTF(InOrderCPU, "sleeping CPU.\n"); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); timesIdled++; } else { //Tick next_tick = curTick() + cycles(1); //tickEvent.schedule(next_tick); - schedule(&tickEvent, nextCycle(curTick() + 1)); + schedule(&tickEvent, clockEdge(1)); DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", - nextCycle(curTick() + 1)); + clockEdge(1)); } } @@ -959,15 +959,10 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst, event_pri); - Tick sked_tick = nextCycle(curTick() + ticks(delay)); - if (delay >= 0) { - DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i, [tid:%i].\n", - eventNames[c_event], curTick() + delay, tid); - schedule(cpu_event, sked_tick); - } else { - cpu_event->process(); - cpuEventRemoveList.push(cpu_event); - } + Tick sked_tick = clockEdge(delay); + DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i, [tid:%i].\n", + eventNames[c_event], curTick() + delay, tid); + schedule(cpu_event, sked_tick); // Broadcast event to the Resource Pool // Need to reset tid just in case this is a dummy instruction @@ -1696,7 +1691,9 @@ InOrderCPU::wakeCPU() DPRINTF(Activity, "Waking up CPU\n"); - Tick extra_cycles = tickToCycles((curTick() - 1) - lastRunningCycle); + Tick extra_cycles = curCycle() - lastRunningCycle; + if (extra_cycles != 0) + --extra_cycles; idleCycles += extra_cycles; for (int stage_num = 0; stage_num < NumStages; stage_num++) { @@ -1705,7 +1702,7 @@ InOrderCPU::wakeCPU() numCycles += extra_cycles; - schedule(&tickEvent, nextCycle(curTick())); + schedule(&tickEvent, nextCycle()); } // Lots of copied full system code...place into BaseCPU class? diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 3103201dd..9a0a62c87 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -204,7 +204,7 @@ class InOrderCPU : public BaseCPU void scheduleTickEvent(int delay) { assert(!tickEvent.scheduled() || tickEvent.squashed()); - reschedule(&tickEvent, nextCycle(curTick() + ticks(delay)), true); + reschedule(&tickEvent, clockEdge(delay), true); } /** Unschedule tick event, regardless of its current state. */ diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index 2ddce13c3..098a4e1b4 100644 --- a/src/cpu/inorder/resource.cc +++ b/src/cpu/inorder/resource.cc @@ -372,7 +372,7 @@ Resource::ticks(int num_cycles) void Resource::scheduleExecution(int slot_num) { - if (latency >= 1) { + if (latency > 0) { scheduleEvent(slot_num, latency); } else { execute(slot_num); diff --git a/src/cpu/inorder/resource_pool.cc b/src/cpu/inorder/resource_pool.cc index 4c01165b8..31511314e 100644 --- a/src/cpu/inorder/resource_pool.cc +++ b/src/cpu/inorder/resource_pool.cc @@ -238,7 +238,7 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst, { assert(delay >= 0); - Tick when = cpu->nextCycle(curTick() + cpu->ticks(delay)); + Tick when = cpu->clockEdge(delay); switch ((int)e_type) { @@ -460,7 +460,7 @@ ResourcePool::ResPoolEvent::scheduleEvent(int delay) { InOrderCPU *cpu = resPool->cpu; assert(!scheduled() || squashed()); - cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true); + cpu->reschedule(this, cpu->clockEdge(delay), true); } /** Unschedule resource event, regardless of its current state. */ -- cgit v1.2.3