From ea5dc1d5dfabd31bdd62c8435f84ea21bf0f61c7 Mon Sep 17 00:00:00 2001 From: Erik Hallnor Date: Thu, 16 Oct 2003 17:02:14 -0400 Subject: [PATCH 1/2] Added to new doxygen configs (posting internally and externally). Changed the default to not use dot to speed testing of documentation for warnings. We probably don't want to release postint and postext since there is information about absolute file locations in them. Doxyfile: Turn of DOT for local testing. --HG-- extra : convert_revision : 04df481c7a238e7745e90a011e43f8c533888567 --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index 387bb8f98..81d9c86ca 100644 --- a/Doxyfile +++ b/Doxyfile @@ -954,7 +954,7 @@ HIDE_UNDOC_RELATIONS = YES # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) -HAVE_DOT = YES +HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and From 4134477369028e04dd265a43753868c01912c465 Mon Sep 17 00:00:00 2001 From: Erik Hallnor Date: Thu, 16 Oct 2003 17:04:18 -0400 Subject: [PATCH 2/2] 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;