diff --git a/configs/example/gem5_library/x86-global-inst-tracker.py b/configs/example/gem5_library/x86-global-inst-tracker.py index 430c064024..61158c80d6 100644 --- a/configs/example/gem5_library/x86-global-inst-tracker.py +++ b/configs/example/gem5_library/x86-global-inst-tracker.py @@ -76,14 +76,16 @@ cache_hierarchy = PrivateL1CacheHierarchy( memory = SingleChannelDDR4_2400("1GB") +# using 9 cores because when using openmp in SE mode, the number of cores +# should be # cores + 1 processor = SimpleProcessor(cpu_type=CPUTypes.TIMING, num_cores=9, isa=ISA.X86) # setup instruction tracker # first, we need to create a global instruction tracker global_inst_tracker = GlobalInstTracker( - # threshold to trigger the event - inst_threshold=100_000_000 + # a list of thresholds to trigger the event + inst_thresholds=[100_000_000, 100_020_000] ) # then, we create a local instruction tracker for each core @@ -123,14 +125,17 @@ def max_inst_handler(): # when it reached this function, it means that it successfully raised # the ExitEvent.MAX_INSTS event print("Reached MAX_INSTS with 100000000 instructions") - print("Changing threshold to 20000") - # we can change the threshold of the global instruction tracker - global_inst_tracker.changeThreshold(20000) - # we need to reset the counter of the global instruction tracker - # the counter does not reset automatically + yield False + print("Reached MAX_INSTS with 100020000 instructions") + # we can get the current counter of the global instruction tracker + print(f"Current counter: {global_inst_tracker.getCounter()}") + # we can reset the counter global_inst_tracker.resetCounter() - m5.stats.dump() - m5.stats.reset() + print(f"After reset, current counter: {global_inst_tracker.getCounter()}") + # we can add new threshold to the global instruction tracker + global_inst_tracker.addThreshold(20000) + # we can get the thresholds + print(f"Current thresholds: {global_inst_tracker.getThresholds()}") yield False print("Reached MAX_INSTS with 20000 instructions") print("Stop listening to instructions") @@ -141,9 +146,7 @@ def max_inst_handler(): # # for tracker in all_trackers: # tracker.startListening() - m5.stats.dump() - m5.stats.reset() - yield False + yield True simulator = Simulator( diff --git a/src/cpu/probes/InstTracker.py b/src/cpu/probes/InstTracker.py index 5d4920b2a9..9ddc677d57 100644 --- a/src/cpu/probes/InstTracker.py +++ b/src/cpu/probes/InstTracker.py @@ -41,13 +41,15 @@ class GlobalInstTracker(SimObject): cxx_class = "gem5::GlobalInstTracker" cxx_exports = [ - PyBindMethod("changeThreshold"), + PyBindMethod("addThreshold"), + PyBindMethod("getCounter"), PyBindMethod("resetCounter"), - PyBindMethod("getThreshold"), + PyBindMethod("getThresholds"), + PyBindMethod("resetThresholds"), ] - inst_threshold = Param.Counter( - "The instruction threshold to trigger an" " exit event" + inst_thresholds = VectorParam.Counter( + "A list of instruction thresholds to trigger an exit event" ) diff --git a/src/cpu/probes/inst_tracker.cc b/src/cpu/probes/inst_tracker.cc index 5e6db6767d..b4857b2247 100644 --- a/src/cpu/probes/inst_tracker.cc +++ b/src/cpu/probes/inst_tracker.cc @@ -81,22 +81,26 @@ LocalInstTracker::stopListening() GlobalInstTracker::GlobalInstTracker(const GlobalInstTrackerParams ¶ms) : SimObject(params), - instCount(0), - instThreshold(params.inst_threshold) + instCount(0) { - DPRINTF(InstTracker, "instThreshold = %lu\n", instThreshold); + for (const auto &threshold : params.inst_thresholds) { + instThresholdSet.insert(threshold); + DPRINTF(InstTracker, "adding the instruction threshold\n" + "instThreshold = %lu\n", threshold); + } + DPRINTF(InstTracker, "instThresholdSet size = %lu\n", + instThresholdSet.size()); } void GlobalInstTracker::updateAndCheckInstCount(const uint64_t& inst) { instCount ++; - if (instCount >= instThreshold) { + if (instThresholdSet.find(instCount) != instThresholdSet.end()) { DPRINTF(InstTracker, "Instruction count reached the threshold\n" - "instCount = %lu\n" - "instThreshold = %lu\n", - instCount, instThreshold); - + "instCount = %lu\n", + instCount); + instThresholdSet.erase(instCount); // note that when the threshold is reached, the simulation will raise // and exit event but it will not reset the instruction counter. // user can reset the counter by calling the resetCounter() function diff --git a/src/cpu/probes/inst_tracker.hh b/src/cpu/probes/inst_tracker.hh index 008da9e9cb..b91b217477 100644 --- a/src/cpu/probes/inst_tracker.hh +++ b/src/cpu/probes/inst_tracker.hh @@ -29,6 +29,8 @@ #ifndef __CPU_PROBES_INST_TRACKER_HH__ #define __CPU_PROBES_INST_TRACKER_HH__ +#include + #include "debug/InstTracker.hh" #include "params/GlobalInstTracker.hh" #include "params/LocalInstTracker.hh" @@ -101,18 +103,24 @@ class GlobalInstTracker : public SimObject uint64_t instCount; /** - * the threshold for the number of instructions that should be executed - * before the simulation exits + * a set of thresholds for the number of instructions that should be + * executed before the simulation exits */ - uint64_t instThreshold; + std::unordered_set instThresholdSet; public: void - changeThreshold(uint64_t new_threshold) + addThreshold(uint64_t new_threshold) { - instThreshold = new_threshold; - DPRINTF(InstTracker, "Changing the instruction threshold\n" - "instThreshold = %lu\n", instThreshold); + instThresholdSet.insert(new_threshold); + DPRINTF(InstTracker, "adding the instruction threshold %lu\n", + new_threshold); + }; + + uint64_t + getCounter() const + { + return instCount; }; void @@ -123,10 +131,17 @@ class GlobalInstTracker : public SimObject "instCount = %lu\n", instCount); }; - uint64_t - getThreshold() const + std::unordered_set + getThresholds() const { - return instThreshold; + return instThresholdSet; + }; + + void + resetThresholds() + { + instThresholdSet.clear(); + DPRINTF(InstTracker, "Resetting the instruction thresholds\n"); }; };