-
Notifications
You must be signed in to change notification settings - Fork 937
Support for OTLP Profile signals #1188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: Francesco Andreuzzi <fandreuz@amazon.com>
src/profiler.cpp
Outdated
otlp_buffer.field(Sample::locations_start_index, frames_seen); | ||
otlp_buffer.field(Sample::locations_length, sampleInfo.num_frames); | ||
|
||
protobuf_mark_t sample_value_mark = otlp_buffer.startMessage(Sample::value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are many tiny messages whose length can be encoded in 1 byte.
Do you want to provide a version of startMessage
(or add an optional argument) to specify maximum length?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the idea is to have an optional argument eventually. Do you want this in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that would be a more valuable optimization than reusing a buffer :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/profiler.cpp
Outdated
otlp_buffer.field(Sample::locations_start_index, frames_seen); | ||
otlp_buffer.field(Sample::locations_length, sampleInfo.num_frames); | ||
|
||
protobuf_mark_t sample_value_mark = otlp_buffer.startMessage(Sample::value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that would be a more valuable optimization than reusing a buffer :)
src/protobuf.cpp
Outdated
void ProtoBuffer::commitMessage(const protobuf_mark_t& mark) { | ||
size_t actual_len = _offset - (mark.message_start + mark.expected_len_byte_count); | ||
size_t actual_len_byte_count = varIntSize(actual_len); | ||
if (actual_len_byte_count > mark.expected_len_byte_count) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an assertion. If reserved space was smaller than required, treat it as error.
Otherwise we may end up moving 100MB blocks without knowing there was a computation mistake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with this. We cannot estimate the size of the message without low level (and error prone) computations at runtime. And any such estimation would be fragile and hard to change later. Any fixed size we decide now may be not enough for long profiling sessions. But either case, I don't think it's a "computation mistake".
Are you implying we should have an exact estimate of the size of the message, before we start writing it to the buffer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, let's call it "underestimation" rather than "computation mistake". I'm saying that startMessage
should accept the maximum size of a message instead of an estimation. 5 bytes (which can encode up to 32 GiB messages) is sufficient for all use cases. So, let's use 5 bytes default for the top-level messages and provide an appropriate upper bound for inner ones. Exact estimate is not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/protobuf.h
Outdated
struct protobuf_mark_t { | ||
size_t message_start; | ||
size_t expected_len_byte_count; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a good practice to return a structure larger than machine word from a function.
64-bit field for a value that needs at most 3 is too much anyway.
It would be natural (in system programming world) to fit protobuf_mark_t
in a machine word or in u64
and pass it by value: 3 bits for len_bytes
and remaining 61 bits for message_start
. You may use either bit-field struct or just u64
and do manipulations by yourself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check 17084fe
src/protobuf.h
Outdated
protobuf_mark_t startMessage(protobuf_index_t index); | ||
void commitMessage(protobuf_mark_t mark); | ||
protobuf_mark_t startMessage(protobuf_index_t index, size_t max_len_byte_count = NESTED_FIELD_BYTE_COUNT); | ||
void commitMessage(const protobuf_mark_t& mark); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not need to be a reference, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, e5e8d33
_output = OUTPUT_TEXT; | ||
_dump_flat = value == NULL ? INT_MAX : atoi(value); | ||
|
||
CASE("otlp") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind updating all relevant docs and examples with new option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, let me know if I forgot something: a90b347
src/profiler.cpp
Outdated
#include "frameName.h" | ||
#include "os.h" | ||
#include "otlp.h" | ||
#include "protobuf.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess protobuf.h is redundant here, since otlp.h already includes it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/protobuf.cpp
Outdated
|
||
for (size_t i = 0; i < max_len_byte_count - 1; ++i) { | ||
size_t idx = message_start + i; | ||
_data[idx] = (unsigned char) (0x80 | (actual_len & 0x7f)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
& 0x7f
is redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already merged PR, but can I ask you to update its description with background, motivation, summary of changes, etc., so we could refer it in the future. Thanks. |
Done, let me know if you'd like to have any changes or additions. |
Looks good, thanks. |
Changes
otlp
) to dump data in OpenTelemetry formatprotobuf.cpp
: Allow specifying the maximum bit count for the varint encoding the length of a nested messageMotivation
OpenTelemetry recently added support for Profile signals. The end goal of the initiative is to provide a standard, vendor-agnostic format for profiling data. Adopting this protocol as one of our supported output formats will help our users integrating Async-Profiler in their workflow easily.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.