From 4134477369028e04dd265a43753868c01912c465 Mon Sep 17 00:00:00 2001 From: Erik Hallnor Date: Thu, 16 Oct 2003 17:04:18 -0400 Subject: [PATCH] Add a commited loads event queue similar to the one for commited instructions. Two new parameters for the CPU models, max_loads_any_thread and max_loads_all_threads. cpu/memtest/memtest.cc: cpu/memtest/memtest.hh: Swap out maxReads for the new commited loads model. --HG-- extra : convert_revision : 35031329bbc476122b2203104537a9f8b46addfa --- cpu/base_cpu.cc | 32 ++++++++++++++++++++++++++++- cpu/base_cpu.hh | 31 +++++++++++++++++++++------- cpu/memtest/memtest.cc | 40 ++++++++++++++++++------------------ cpu/memtest/memtest.hh | 13 ++++++------ cpu/simple_cpu/simple_cpu.cc | 23 ++++++++++++++++++++- cpu/simple_cpu/simple_cpu.hh | 6 ++++++ 6 files changed, 109 insertions(+), 36 deletions(-) diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc index 90785946e..2e1d95d88 100644 --- a/cpu/base_cpu.cc +++ b/cpu/base_cpu.cc @@ -49,13 +49,17 @@ int maxThreadsPerCPU = 1; BaseCPU::BaseCPU(const string &_name, int _number_of_threads, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, + Counter max_loads_all_threads, System *_system, int num, Tick freq) : SimObject(_name), number(num), frequency(freq), number_of_threads(_number_of_threads), system(_system) #else BaseCPU::BaseCPU(const string &_name, int _number_of_threads, Counter max_insts_any_thread, - Counter max_insts_all_threads) + Counter max_insts_all_threads, + Counter max_loads_any_thread, + Counter max_loads_all_threads) : SimObject(_name), number_of_threads(_number_of_threads) #endif { @@ -90,6 +94,32 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, max_insts_all_threads, *counter); } + // allocate per-thread load-based event queues + comLoadEventQueue = new (EventQueue *)[number_of_threads]; + for (int i = 0; i < number_of_threads; ++i) + comLoadEventQueue[i] = new EventQueue("load-based event queue"); + + // + // set up instruction-count-based termination events, if any + // + if (max_loads_any_thread != 0) + for (int i = 0; i < number_of_threads; ++i) + new SimExitEvent(comLoadEventQueue[i], max_loads_any_thread, + "a thread reached the max load count"); + + if (max_loads_all_threads != 0) { + // allocate & initialize shared downcounter: each event will + // decrement this when triggered; simulation will terminate + // when counter reaches 0 + int *counter = new int; + *counter = number_of_threads; + for (int i = 0; i < number_of_threads; ++i) + new CountedExitEvent(comLoadEventQueue[i], + "all threads reached the max load count", + max_loads_all_threads, *counter); + } + + #ifdef FULL_SYSTEM memset(interrupts, 0, sizeof(interrupts)); intstatus = 0; diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh index d5c3b68d8..5946ced2f 100644 --- a/cpu/base_cpu.hh +++ b/cpu/base_cpu.hh @@ -81,27 +81,41 @@ class BaseCPU : public SimObject #ifdef FULL_SYSTEM BaseCPU(const std::string &_name, int _number_of_threads, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, Counter max_loads_all_threads, System *_system, int num, Tick freq); #else BaseCPU(const std::string &_name, int _number_of_threads, Counter max_insts_any_thread = 0, - Counter max_insts_all_threads = 0); + Counter max_insts_all_threads = 0, + Counter max_loads_any_thread = 0, + Counter max_loads_all_threads = 0); #endif virtual ~BaseCPU() {} virtual void regStats(); - /// Number of threads we're actually simulating (<= SMT_MAX_THREADS). - /// This is a constant for the duration of the simulation. + /** + * Number of threads we're actually simulating (<= SMT_MAX_THREADS). + * This is a constant for the duration of the simulation. + */ int number_of_threads; - /// Vector of per-thread instruction-based event queues. Used for - /// scheduling events based on number of instructions committed by - /// a particular thread. + /** + * Vector of per-thread instruction-based event queues. Used for + * scheduling events based on number of instructions committed by + * a particular thread. + */ EventQueue **comInsnEventQueue; + /** + * Vector of per-thread load-based event queues. Used for + * scheduling events based on number of loads committed by + *a particular thread. + */ + EventQueue **comLoadEventQueue; + #ifdef FULL_SYSTEM System *system; #endif @@ -109,7 +123,10 @@ class BaseCPU : public SimObject virtual bool filterThisInstructionPrefetch(int thread_number, short asid, Addr prefetchTarget) const { return true; } - /// Return pointer to CPU's branch predictor (NULL if none). + /** + * Return pointer to CPU's branch predictor (NULL if none). + * @return Branch predictor pointer. + */ virtual BranchPred *getBranchPred() { return NULL; }; private: diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 9deebb282..6292911cd 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -51,10 +51,11 @@ MemTest::MemTest(const string &name, unsigned _memorySize, unsigned _percentReads, unsigned _percentUncacheable, - unsigned _maxReads, unsigned _progressInterval, - Addr _traceAddr) - : BaseCPU(name, 1), + Addr _traceAddr, + Counter max_loads_any_thread, + Counter max_loads_all_threads) + : BaseCPU(name, 1, 0, 0, max_loads_any_thread, max_loads_all_threads), tickEvent(this), cacheInterface(_cache_interface), mainMem(main_mem), @@ -62,7 +63,6 @@ MemTest::MemTest(const string &name, size(_memorySize), percentReads(_percentReads), percentUncacheable(_percentUncacheable), - maxReads(_maxReads), progressInterval(_progressInterval), nextProgressMessage(_progressInterval) { @@ -136,19 +136,13 @@ MemTest::completeRequest(MemReqPtr req, uint8_t *data) numReads++; - if (numReads.val() == nextProgressMessage) { - cerr << name() << ": completed " << numReads.val() + if (numReads.value() == nextProgressMessage) { + cerr << name() << ": completed " << numReads.value() << " read accesses @ " << curTick << endl; nextProgressMessage += progressInterval; } - if (numReads.val() == maxReads) { - stringstream stream; - stream << name() << " reached max read count (" << maxReads - << ")" << endl; - - new SimExitEvent(stream.str()); - } + comLoadEventQueue[0]->serviceEvents(numReads.value()); break; case Write: @@ -289,9 +283,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest) Param memory_size; Param percent_reads; Param percent_uncacheable; - Param max_reads; Param progress_interval; Param trace_addr; + Param max_loads_any_thread; + Param max_loads_all_threads; END_DECLARE_SIM_OBJECT_PARAMS(MemTest) @@ -304,10 +299,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest) INIT_PARAM_DFLT(memory_size, "memory size", 65536), INIT_PARAM_DFLT(percent_reads, "target read percentage", 65), INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10), - INIT_PARAM_DFLT(max_reads, "number of reads to simulate", 0), INIT_PARAM_DFLT(progress_interval, "progress report interval (in accesses)", 1000000), - INIT_PARAM_DFLT(trace_addr, "address to trace", 0) + INIT_PARAM_DFLT(trace_addr, "address to trace", 0), + INIT_PARAM_DFLT(max_loads_any_thread, + "terminate when any thread reaches this load count", + 0), + INIT_PARAM_DFLT(max_loads_all_threads, + "terminate when all threads have reached this load count", + 0) END_INIT_SIM_OBJECT_PARAMS(MemTest) @@ -315,10 +315,10 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest) CREATE_SIM_OBJECT(MemTest) { return new MemTest(getInstanceName(), cache->getInterface(), main_mem, - check_mem, - memory_size, percent_reads, - percent_uncacheable, max_reads, progress_interval, - trace_addr); + check_mem, memory_size, percent_reads, + percent_uncacheable, progress_interval, + trace_addr, max_loads_any_thread, + max_loads_all_threads); } REGISTER_SIM_OBJECT("MemTest", MemTest) diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 36c9691e6..bda807d11 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -49,9 +49,10 @@ class MemTest : public BaseCPU unsigned _memorySize, unsigned _percentReads, unsigned _percentUncacheable, - unsigned _maxReads, unsigned _progressInterval, - Addr _traceAddr); + Addr _traceAddr, + Counter max_loads_any_thread, + Counter max_loads_all_threads); // register statistics virtual void regStats(); @@ -82,8 +83,6 @@ class MemTest : public BaseCPU unsigned percentReads; // target percentage of read accesses unsigned percentUncacheable; - Tick maxReads; // max # of reads to perform (then quit) - unsigned blockSize; Addr blockAddrMask; @@ -104,9 +103,9 @@ class MemTest : public BaseCPU Tick noResponseCycles; - Statistics::Scalar numReads; - Statistics::Scalar numWrites; - Statistics::Scalar numCopies; + Statistics::Scalar<> numReads; + Statistics::Scalar<> numWrites; + Statistics::Scalar<> numCopies; // called by MemCompleteEvent::process() void completeRequest(MemReqPtr req, uint8_t *data); diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index f4fc1b823..28009b7f0 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -104,6 +104,8 @@ SimpleCPU::SimpleCPU(const string &_name, System *_system, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, + Counter max_loads_all_threads, AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem, MemInterface *icache_interface, @@ -111,15 +113,19 @@ SimpleCPU::SimpleCPU(const string &_name, int cpu_id, Tick freq) : BaseCPU(_name, /* number_of_threads */ 1, max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads, _system, cpu_id, freq), #else SimpleCPU::SimpleCPU(const string &_name, Process *_process, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, + Counter max_loads_all_threads, MemInterface *icache_interface, MemInterface *dcache_interface) : BaseCPU(_name, /* number_of_threads */ 1, - max_insts_any_thread, max_insts_all_threads), + max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads), #endif tickEvent(this), xc(NULL), cacheCompletionEvent(this) { @@ -636,6 +642,11 @@ SimpleCPU::tick() numMemRefs++; } + if (si->isLoad()) { + ++numLoad; + comLoadEventQueue[0]->serviceEvents(numLoad); + } + if (traceData) traceData->finalize(); @@ -679,6 +690,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) Param max_insts_any_thread; Param max_insts_all_threads; + Param max_loads_any_thread; + Param max_loads_all_threads; #ifdef FULL_SYSTEM SimObjectParam itb; @@ -704,6 +717,12 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) INIT_PARAM_DFLT(max_insts_all_threads, "terminate when all threads have reached this insn count", 0), + INIT_PARAM_DFLT(max_loads_any_thread, + "terminate when any thread reaches this load count", + 0), + INIT_PARAM_DFLT(max_loads_all_threads, + "terminate when all threads have reached this load count", + 0), #ifdef FULL_SYSTEM INIT_PARAM(itb, "Instruction TLB"), @@ -730,6 +749,7 @@ CREATE_SIM_OBJECT(SimpleCPU) return new SimpleCPU(getInstanceName(), system, max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads, itb, dtb, mem, (icache) ? icache->getInterface() : NULL, (dcache) ? dcache->getInterface() : NULL, @@ -738,6 +758,7 @@ CREATE_SIM_OBJECT(SimpleCPU) return new SimpleCPU(getInstanceName(), workload, max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads, icache->getInterface(), dcache->getInterface()); #endif // FULL_SYSTEM diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 658a92344..fd50acfe1 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -114,6 +114,7 @@ class SimpleCPU : public BaseCPU SimpleCPU(const std::string &_name, System *_system, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, Counter max_loads_all_threads, AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem, MemInterface *icache_interface, MemInterface *dcache_interface, int cpu_id, Tick freq); @@ -123,6 +124,8 @@ class SimpleCPU : public BaseCPU SimpleCPU(const std::string &_name, Process *_process, Counter max_insts_any_thread, Counter max_insts_all_threads, + Counter max_loads_any_thread, + Counter max_loads_all_threads, MemInterface *icache_interface, MemInterface *dcache_interface); #endif @@ -239,6 +242,9 @@ class SimpleCPU : public BaseCPU // number of simulated memory references Statistics::Scalar<> numMemRefs; + // number of simulated loads + Counter numLoad; + // number of idle cycles Statistics::Scalar<> idleCycles; Statistics::Formula idleFraction; -- 2.30.2