Go to the documentation of this file.
45 #include "debug/ElasticTrace.hh"
59 depWindowSize(params.depWindowSize),
60 dataTraceStream(
nullptr),
61 instTraceStream(
nullptr),
62 startTraceInst(params.startTraceInst),
64 traceVirtAddr(params.traceVirtAddr),
67 cpu =
dynamic_cast<CPU *
>(params.manager);
69 cpu->getContext(0)->getIsaPtr()->regClasses();
72 fatal_if(!cpu,
"Manager of %s is not of type O3CPU and thus does not "\
73 "support dependency tracing.\n",
name());
75 fatal_if(depWindowSize == 0,
"depWindowSize parameter must be non-zero. "\
76 "Recommended size is 3x ROB size in the O3CPU.\n");
78 fatal_if(cpu->numThreads > 1,
"numThreads = %i, %s supports tracing for"\
79 "single-threaded workload only", cpu->numThreads,
name());
81 fatal_if(params.instFetchTraceFile ==
"",
"Assign instruction fetch "\
82 "trace file path to instFetchTraceFile");
83 fatal_if(params.dataDepTraceFile ==
"",
"Assign data dependency "\
84 "trace file path to dataDepTraceFile");
86 params.instFetchTraceFile);
91 ProtoMessage::PacketHeader inst_pkt_header;
92 inst_pkt_header.set_obj_id(
name());
94 instTraceStream->write(inst_pkt_header);
97 ProtoMessage::InstDepRecordHeader data_rec_header;
98 data_rec_header.set_obj_id(
name());
100 data_rec_header.set_window_size(depWindowSize);
101 dataTraceStream->write(data_rec_header);
109 inform(
"@%llu: regProbeListeners() called, startTraceInst = %llu",
127 inform(
"@%llu: No. of instructions committed = %llu, registering elastic"
159 req->getPC(), req->getVaddr(), req->getPaddr(),
160 req->getFlags(), req->getSize(),
curTick());
165 inst_fetch_pkt.set_tick(
curTick());
167 inst_fetch_pkt.set_pc(req->getPC());
168 inst_fetch_pkt.set_flags(req->getFlags());
169 inst_fetch_pkt.set_addr(req->getPaddr());
170 inst_fetch_pkt.set_size(req->getSize());
186 has already retired (mostly squashed)", dyn_inst->seqNum);
199 auto itr_exec_info =
tempStore.find(dyn_inst->seqNum);
201 exec_info_ptr = itr_exec_info->second;
204 tempStore[dyn_inst->seqNum] = exec_info_ptr;
219 auto itr_exec_info =
tempStore.find(dyn_inst->seqNum);
222 " skipping.\n", dyn_inst->seqNum);
250 int8_t max_regs = dyn_inst->numSrcRegs();
251 for (
int src_idx = 0; src_idx < max_regs; src_idx++) {
253 const RegId& src_reg = dyn_inst->srcRegIdx(src_idx);
257 PhysRegIdPtr phys_src_reg = dyn_inst->regs.renamedSrcIdx(src_idx);
259 " %i (%s)\n", seq_num,
281 max_regs = dyn_inst->numDestRegs();
282 for (
int dest_idx = 0; dest_idx < max_regs; dest_idx++) {
285 const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
291 dyn_inst->regs.renamedDestIdx(dest_idx);
293 " %i (%s)\n", seq_num, phys_dest_reg->
flatIndex(),
306 inst_reg_pair.second);
307 auto itr_regdep_map =
physRegDepMap.find(inst_reg_pair.second);
318 auto itr_exec_info =
tempStore.find(head_inst->seqNum);
330 head_inst->hasRequest() &&
331 head_inst->getFault() ==
NoFault) {
347 if (!head_inst->isNop()) {
353 auto itr_temp_store =
tempStore.find(head_inst->seqNum);
356 "store, skipping.\n", head_inst->seqNum);
376 if (head_inst->getFault() !=
NoFault) {
378 "skip adding it to the trace\n",
379 (head_inst->isMemRef() ?
"Load/store" :
"Comp inst."),
381 }
else if (head_inst->isMemRef() && !head_inst->hasRequest()) {
383 "skip adding it to the trace\n", head_inst->seqNum);
384 }
else if (!head_inst->readPredicate()) {
386 "skip adding it to the trace\n",
387 (head_inst->isMemRef() ?
"Load/store" :
"Comp inst."),
409 new_record->
instNum = head_inst->seqNum;
410 new_record->
commit = commit;
411 new_record->
type = head_inst->isLoad() ? Record::LOAD :
412 (head_inst->isStore() ? Record::STORE :
416 new_record->
reqFlags = head_inst->memReqFlags;
417 new_record->
virtAddr = head_inst->effAddr;
418 new_record->
physAddr = head_inst->physEffAddr;
420 new_record->
size = head_inst->effSize;
421 new_record->
pc = head_inst->instAddr();
447 if (head_inst->isLoad() && !commit) {
452 std::set<InstSeqNum>::const_iterator dep_set_it;
462 "%lli\n", new_record->
instNum, *dep_set_it);
463 TraceInfo* reg_dep = trace_info_itr->second;
479 "%lli is skipped\n",new_record->
instNum, *dep_set_it);
487 if (head_inst->isStore()) {
508 (commit ?
"committed" :
"squashed"), new_record->
instNum);
529 bool find_load_not_store)
537 uint32_t num_go_back = 0;
542 while (num_go_back <
depWindowSize && from_itr != until_itr) {
543 if (find_load_not_store) {
563 past_record = *from_itr;
577 uint32_t num_go_back = 0;
578 Tick execute_tick = 0;
580 if (new_record->
isLoad()) {
584 }
else if (new_record->
isStore()) {
597 while (num_go_back <
depWindowSize && from_itr != until_itr) {
609 past_record = *from_itr;
632 Tick execute_tick)
const
639 Tick execute_tick)
const
647 Tick execute_tick)
const
656 Tick execute_tick)
const
669 auto itr_exec_info =
tempStore.find(temp_sn);
673 delete exec_info_ptr;
689 int64_t comp_delay = -1;
690 Tick execution_tick = 0, completion_tick = 0;
699 if (past_record->
isLoad()) {
705 }
else if (past_record->
isStore()) {
707 }
else if (past_record->
isComp()){
710 assert(execution_tick >= completion_tick);
711 comp_delay = execution_tick - completion_tick;
714 execution_tick, completion_tick, comp_delay);
733 int64_t comp_delay = -1;
734 Tick execution_tick = 0, completion_tick = 0;
752 assert(execution_tick >= completion_tick);
753 comp_delay = execution_tick - completion_tick;
755 execution_tick, completion_tick, comp_delay);
799 uint16_t num_filtered_nodes = 0;
802 while (num_to_write > 0) {
804 assert(temp_ptr->
type != Record::INVALID);
811 "is as follows:\n", temp_ptr->
instNum);
815 "size %i, flags %i\n", temp_ptr->
physAddr,
823 }
else if (temp_ptr->
isStore()) {
834 ProtoMessage::InstDepRecord dep_pkt;
835 dep_pkt.set_seq_num(temp_ptr->
instNum);
836 dep_pkt.set_type(temp_ptr->
type);
837 dep_pkt.set_pc(temp_ptr->
pc);
839 dep_pkt.set_flags(temp_ptr->
reqFlags);
840 dep_pkt.set_p_addr(temp_ptr->
physAddr);
844 dep_pkt.set_v_addr(temp_ptr->
virtAddr);
845 dep_pkt.set_size(temp_ptr->
size);
847 dep_pkt.set_comp_delay(temp_ptr->
compDelay);
854 dep_pkt.add_rob_dep(temp_ptr->
robDepList.front());
866 if (num_filtered_nodes != 0) {
871 dep_pkt.set_weight(num_filtered_nodes);
872 num_filtered_nodes = 0;
880 ++num_filtered_nodes;
887 depTrace.erase(dep_trace_itr_start, dep_trace_itr);
891 : statistics::
Group(parent),
892 ADD_STAT(numRegDep, statistics::units::Count::get(),
893 "Number of register dependencies recorded during tracing"),
894 ADD_STAT(numOrderDepStores, statistics::units::Count::get(),
895 "Number of commit order (rob) dependencies for a store "
896 "recorded on a past load/store during tracing"),
897 ADD_STAT(numIssueOrderDepLoads, statistics::units::Count::get(),
898 "Number of loads that got assigned issue order dependency "
899 "because they were dependency-free"),
900 ADD_STAT(numIssueOrderDepStores, statistics::units::Count::get(),
901 "Number of stores that got assigned issue order dependency "
902 "because they were dependency-free"),
903 ADD_STAT(numIssueOrderDepOther, statistics::units::Count::get(),
904 "Number of non load/store insts that got assigned issue order "
905 "dependency because they were dependency-free"),
906 ADD_STAT(numFilteredNodes, statistics::units::Count::get(),
907 "No. of nodes filtered out before writing the output trace"),
908 ADD_STAT(maxNumDependents, statistics::units::Count::get(),
909 "Maximum number or dependents on any instruction"),
910 ADD_STAT(maxTempStoreSize, statistics::units::Count::get(),
911 "Maximum size of the temporary store during the run"),
912 ADD_STAT(maxPhysRegDepMapSize, statistics::units::Count::get(),
913 "Maximum size of register dependency map")
920 return Record::RecordType_Name(
type);
Tick curTick()
The universal simulation clock.
bool allProbesReg
Whther the elastic trace listener has been registered for all probes.
void write(const google::protobuf::Message &msg)
Write a message to the stream, preprending it with the message size.
std::list< InstSeqNum > physRegDepList
constexpr decltype(nullptr) NoFault
ElasticTraceStats(statistics::Group *parent)
The elastic trace is a type of probe listener and listens to probe points in multiple stages of the O...
void updateIssueOrderDep(TraceInfo *new_record)
Reverse iterate through the graph, search for an issue order dependency for a new node and update the...
CPU * cpu
Pointer to the O3CPU that is this listener's parent a.k.a.
void fetchReqTrace(const RequestPtr &req)
Take the fields of the request class object that are relevant to create an instruction fetch request.
void recordExecTick(const DynInstConstPtr &dyn_inst)
Populate the execute timestamp field in an InstExecInfo object for an instruction in flight.
void recordToCommTick(const DynInstConstPtr &dyn_inst)
Populate the timestamp field in an InstExecInfo object for an instruction in flight when it is execut...
bool firstWin
Used for checking the first window for processing and writing of dependency trace.
std::vector< ProbeListener * > listeners
void regProbeListeners()
Register the probe listeners that is the methods called on a probe point notify() call.
ElasticTrace(const ElasticTraceParams ¶ms)
Constructor.
void addCommittedInst(const DynInstConstPtr &head_inst)
Add an instruction that is at the head of the ROB and is committed.
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
statistics::Scalar numFilteredNodes
Number of filtered nodes.
@ MiscRegClass
Control (misc) register.
This class is a minimal wrapper around SimObject.
ProbeListenerArg generates a listener for the class of Arg and the class type T which is the class co...
bool hasLoadBeenSent(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a load sent earlier than the execute tick.
RegIndex index() const
Index accessors.
statistics::Scalar numIssueOrderDepStores
Number of store insts that got assigned an issue order dependency because they were dependency-free.
If you want a reference counting pointer to a mutable object, create it like this:
EventFunctionWrapper regEtraceListenersEvent
Event to trigger registering this listener for all probe points.
Tick executeTick
Timestamp when instruction was first processed by execute stage.
bool is(RegClass reg_class) const
void flushTraces()
Process any outstanding trace records, flush them out to the protobuf output streams and delete the s...
const std::string & typeToStr() const
Return string specifying the type of the node.
bool hasStoreCommitted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a store sent earlier than the execute tick.
const RegIndex & flatIndex() const
Flat index accessor.
void addDepTraceRecord(const DynInstConstPtr &head_inst, InstExecInfo *exec_info_ptr, bool commit)
Add a record to the dependency trace depTrace which is a sequential container.
std::list< InstSeqNum > robDepList
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
bool isComp() const
Is the record a fetch triggering an Icache request.
std::unordered_map< RegIndex, InstSeqNum > physRegDepMap
Map for recording the producer of a physical register to check Read After Write dependencies.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
int64_t compDelay
Computational delay after the last dependent inst.
void clearTempStoreUntil(const DynInstConstPtr &head_inst)
Clear entries in the temporary store of execution info objects to free allocated memory until the pre...
InstSeqNum lastClearedSeqNum
The last cleared instruction sequence number used to free up the memory allocated in the temporary st...
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Tick
Tick count type.
std::shared_ptr< Request > RequestPtr
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
statistics::Scalar maxTempStoreSize
Maximum size of the temporary store mostly useful as a check that it is not growing.
statistics::Scalar numIssueOrderDepOther
Number of non load/store insts that got assigned an issue order dependency because they were dependen...
void compDelayPhysRegDep(TraceInfo *past_record, TraceInfo *new_record)
Calculate the computational delay between an instruction and a subsequent instruction that has a Phys...
ProtoOutputStream * dataTraceStream
Protobuf output stream for data dependency trace.
void writeDepTrace(uint32_t num_to_write)
Write out given number of records to the trace starting with the first record in depTrace and iterati...
std::unordered_map< InstSeqNum, TraceInfo * > traceInfoMap
Map where the instruction sequence number is mapped to the pointer to the TraceInfo object.
static Counter numSimulatedInsts()
bool hasLoadCompleted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a load that completed earlier than the execute tick.
Tick toCommitTick
Timestamp when instruction execution is completed in execute stage and instruction is marked as ready...
const InstSeqNum startTraceInst
Number of instructions after which to enable tracing.
const char * className() const
Return a const char* with the register class name.
RecordType type
The type of trace record for the instruction node.
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
uint32_t depWindowSize
The maximum distance for a dependency and is set by a top level level parameter.
void addSquashedInst(const DynInstConstPtr &head_inst)
Add an instruction that is at the head of the ROB and is squashed only if it is a load and a request ...
const std::string & name()
void removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair)
When an instruction gets squashed the destination register mapped to it is freed up in the rename sta...
virtual void scheduleInstCountEvent(Event *event, Tick count)=0
std::set< InstSeqNum > physRegDepSet
Set of instruction sequence numbers that this instruction depends on due to Read After Write data dep...
const char * className() const
Return a const char* with the register class name.
Request::FlagsType reqFlags
std::reverse_iterator< depTraceItr > depTraceRevItr
Typedef of the reverse iterator to the instruction dependency trace.
void compDelayRob(TraceInfo *past_record, TraceInfo *new_record)
Calculate the computational delay between an instruction and a subsequent instruction that has an ROB...
gem5::o3::ElasticTrace::ElasticTraceStats stats
statistics::Scalar maxPhysRegDepMapSize
Maximum size of the map that holds the last writer to a physical register.
const bool traceVirtAddr
Whether to trace virtual addresses for memory requests.
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
statistics::Scalar numIssueOrderDepLoads
Number of load insts that got assigned an issue order dependency because they were dependency-free.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
@ IntRegClass
Integer register.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
bool isLoad() const
Is the record a load.
statistics::Scalar numRegDep
Number of register dependencies recorded during tracing.
bool hasCompCompleted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a comp node that completed earlier than the execute tick.
void updateRegDep(const DynInstConstPtr &dyn_inst)
Record a Read After Write physical register dependency if there has been a write to the source regist...
A ProtoOutputStream wraps a coded stream, potentially with compression, based on looking at the file ...
void assignRobDep(TraceInfo *past_record, TraceInfo *new_record)
The new_record has an order dependency on a past_record, thus update the new record's Rob dependency ...
void updateCommitOrderDep(TraceInfo *new_record, bool find_load_not_store)
Reverse iterate through the graph, search for a store-after-store or store-after-load dependency and ...
void regEtraceListeners()
Register all listeners.
std::vector< TraceInfo * > depTrace
The instruction dependency trace containing TraceInfo objects.
statistics::Scalar maxNumDependents
Maximum number of dependents on any instruction.
ProtoOutputStream * instTraceStream
Protobuf output stream for instruction fetch trace.
std::unordered_map< InstSeqNum, InstExecInfo * > tempStore
Temporary store of InstExecInfo objects.
std::vector< TraceInfo * >::iterator depTraceItr
Typedef of iterator to the instruction dependency trace.
bool isStore() const
Is the record a store.
Register ID: describe an architectural register with its class and index.
Tick getExecuteTick() const
Get the execute tick of the instruction.
Counter value() const
Return the current value of this stat as its base type.
Generated on Tue Sep 21 2021 12:25:05 for gem5 by doxygen 1.8.17