perf: add annotations for non-concurrent cross-scoped duration measurements#13960
perf: add annotations for non-concurrent cross-scoped duration measurements#13960mattklein123 merged 7 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
|
|
||
| void PerfAnnotationContext::begin(absl::string_view category, absl::string_view description) { | ||
| const CategoryDescription key = {std::string(category), std::string(description)}; | ||
| RELEASE_ASSERT(!timestamps_map_.contains(key), |
There was a problem hiding this comment.
RELEASE_ASSERT use seems risky. Are these begin/end annotations meant to be used across event loop events or only within a single call stack?
There was a problem hiding this comment.
Within a single call stack only unfortunately. Would be nice to have uniquely identifiable events in the event loop though. Is it possible?
There was a problem hiding this comment.
I think it's OK to use RELEASE_ASSERT as this code will only be activated when the binary is compiled with perf annotation enabled.
And it wouldn't do any good to use ASSERT because you generally would want opt-builds for measuring performance.
There was a problem hiding this comment.
There's a better way to do all of this: have an RAII object that is kept around for the duration of the perf operation and keeps the necessary state instead of keeping the state on a global as a string in a map.
It nicely solves the issue of concurrent performance measurements and works across call stacks.
There was a problem hiding this comment.
Yeah for cases where RAII is OK, that works today with PERF_OPERATION which is just a wrapper that has all the code compile to nothing when perf annotations are not compiled in. I think that should be preferred when feasible to use.
I assume that PERF_BEGIN and PERF_END are where the plumbing needed to hold an object seems not worth it, and correlating by string seems worth it. It doesn't look to me like this adds any overhead when not used, so that's why I'm OK with this if it makes annotations easier to implement.
There was a problem hiding this comment.
The cleanest way though is just for begin() to return an object that you store in your filter undef ifdef
A-ha, now I see. In this case the owning object (e.g. filter) needs to be annotated too. And it has to be the same for a pair of begin() and end(). Right?
There was a problem hiding this comment.
Yeah though I think the logical next step of what I suggested is that rather than calling begin() you just instantiate an RAII object yourself, throwing it in an ifdef'd member variable in (say) the filter; maybe via unique_ptr, and destructing it works like end().
There was a problem hiding this comment.
Yes, exactly, ^ is what I'm proposing. I think we can make it so it compiles to nothing if annotations are not enabled.
There was a problem hiding this comment.
Updated. Turned out it's enough to add a few new macros to achieve the same result.
jmarantz
left a comment
There was a problem hiding this comment.
nice. Just some trivial comments.
|
|
||
| void PerfAnnotationContext::begin(absl::string_view category, absl::string_view description) { | ||
| const CategoryDescription key = {std::string(category), std::string(description)}; | ||
| RELEASE_ASSERT(!timestamps_map_.contains(key), |
There was a problem hiding this comment.
I think it's OK to use RELEASE_ASSERT as this code will only be activated when the binary is compiled with perf annotation enabled.
And it wouldn't do any good to use ASSERT because you generally would want opt-builds for measuring performance.
| const CategoryDescription key = {std::string(category), std::string(description)}; | ||
| const MonotonicTime end_time = currentTime(); | ||
| const auto result = timestamps_map_.extract(key); | ||
| RELEASE_ASSERT(!result.empty(), "double perf measurement ending is disallowed!"); |
There was a problem hiding this comment.
might as well include the category & description in this message and the RELEASE_ASSERT above.
|
|
||
| /** | ||
| * Initiates a duration measurement which can be finished in a different scope. | ||
| * Please note that this kind of measurements makes sense only in a strictly |
There was a problem hiding this comment.
s/this/these/
s/makes/make/
| * Initiates a duration measurement which can be finished in a different scope. | ||
| * Please note that this kind of measurements makes sense only in a strictly | ||
| * sequential flow, i.e. when a new stream isn't created until the current one | ||
| * is destroyed. |
There was a problem hiding this comment.
This in reference only to a particular combination of category and description, right?
| { PERF_BEGIN("gamma", "4"); } | ||
| { PERF_BEGIN("sigma", "5"); } | ||
| { PERF_END("gamma", "4"); } | ||
| { PERF_END("sigma", "5"); } |
There was a problem hiding this comment.
Can you also add begin/end checking with same-category different-description and vice versa?
| * shown as separate columns in the generated output table. Before ending the | ||
| * measurement must be started first with a begin() call. The measurement can | ||
| * be started and ended in different scopes, but the flow of these start and | ||
| * stop points for the same category and description must be strictly sequential. |
There was a problem hiding this comment.
seems like you don't need to repeat all of this paragraph from above, but could just reference the doc in begin().
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
jmarantz
left a comment
There was a problem hiding this comment.
@envoyproxy/senior-maintainers
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
|
Can you check coverage? /wait |
|
/retest |
|
Retrying Azure Pipelines: |
@mattklein123 Looks it was a CI glitch. Everything is Ok now. |
…ements (envoyproxy#13960) Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com> Signed-off-by: Qin Qin <qqin@google.com>
Commit Message: perf: add annotations for non-concurrent cross-scoped duration measurements
Additional Description:
Risk Level: Low
Testing: updated unit tests
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A
Fixes #13860