[Lldb-commits] [PATCH] D122603: [wip][intelpt] Refactor timestamps out of `IntelPTInstruction`
walter erquinigo via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 28 12:16:14 PDT 2022
wallace requested changes to this revision.
wallace added inline comments.
This revision now requires changes to proceed.
================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:94-96
+ auto last_ts = m_instruction_timestamps[m_instruction_timestamps.size() - 1];
+ if (last_ts != time)
+ m_instruction_timestamps.emplace(m_instructions.size() - 1, time);
----------------
doing [] is O(logn), and we want to be faster than this.
You can do the following which is O(1)
auto it = m_instruction_timestamps.end()
if (it != m_instruction_timestamps.begin()) {
it--;
if (it->second != tsc) {
// this tsc is not the same!
m_instruction_timestamps.insert(insn_idx, tsc);
} else {
// this tsc is the same, do nothing
}
}
you can further optimize this by storing the last tsc that has been appended, that way you don't even need to create iterators
================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:109-112
+ auto insn_ts = m_instruction_timestamps.find(index);
+ if (!m_instruction_timestamps.empty() && insn_ts != m_instruction_timestamps.end())
+ return insn_ts->second;
+ return 0;
----------------
this is wrong, you need to use upper_bound - 1, like this:
if (m_instruction_timestamps.empty())
return None;
auto it = m_instruction_timestamps.upper_bound(insn_idx);
if (it == m_instruction_timestamps.begin())
return None;
--it;
return it->second;
this will allow you to go to the largest index that is <= than insn_idx
================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:141-142
+ /// Get timestamp of an instruction by its index.
+ uint64_t GetInstructionTimestamp(size_t index) const;
+
----------------
wallace wrote:
> This has to be an optional because it might not be present
better use insn_idx instead of index for all these variables
================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:144-148
+ /// Check if the instruction at a given index was an error.
+ /// -- Reasoning (this will be removed before committing)
+ /// This is faster and less wasteful of memory than creating an ArrayRef
+ /// every time that you need to check this, with GetInstructions()[i].IsError()
+ bool GetInstructionIsError(size_t insn_idx) const;
----------------
I actually like this, let's improve it
================
Comment at: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp:153-154
} else {
- decoded_thread_sp->AppendInstruction(insn, time);
+ decoded_thread_sp->AppendInstruction(insn);
+ decoded_thread_sp->AppendInstructionTimestamp(time);
}
----------------
================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:25
"a trace should have at least one instruction or error");
m_pos = m_decoded_thread_sp->GetInstructions().size() - 1;
}
----------------
here you need to set the correct value of m_current_tsc
================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:43-44
m_pos += IsForwards() ? 1 : -1;
+ if (uint64_t ts = m_decoded_thread_sp->GetInstructionTimestamp(m_pos) != 0)
+ m_currentts = ts;
if (!m_ignore_errors && IsError())
----------------
this will be O(logn). We can do better if m_current_tsc is the following little structure
class DecodedThread {
struct TscRange {
size_t start_index;
size_t end_index;
size_t tsc;
std::map<size_t, uint64_t>::iterator prev;
std::map<size_t, uint64_t>::iterator next;
};
}
Optional<TscRange> m_current_tsc;
Then you can ask the new method `Optional<TscRange> DecodedThread::GetTSCRange(size_t insn_index)` which will give you the entire range of the tsc that covers insn_index. With these numbers, you can do a comparison in this line to very quickly move from TSC to TSC only when needed.
You can also have the method `DecodedThread::GetNextTscRange(const TscRange& range)` that computes in O(1) the next range, and you can similarly have GetPrevTscRange()`. The iterators will help you do that withing using lower_bound, which is O(1)
================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:75
return std::abs(dist);
}
}
----------------
you need to calculate the new tsc_range after moving m_pos
================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h:45-46
size_t m_pos;
+ /// Current instruction timestamp.
+ uint64_t m_currentts;
};
----------------
Optional<uint64_t> m_current_tsc;
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122603/new/
https://reviews.llvm.org/D122603
More information about the lldb-commits
mailing list