-
Notifications
You must be signed in to change notification settings - Fork 375
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
[PROF-7252] Add Profiling.allocation_count
API for new profiler
#2635
Merged
ivoanjo
merged 8 commits into
master
from
ivoanjo/prof-7252-profiling-newobj-tracepoint
Feb 22, 2023
Merged
[PROF-7252] Add Profiling.allocation_count
API for new profiler
#2635
ivoanjo
merged 8 commits into
master
from
ivoanjo/prof-7252-profiling-newobj-tracepoint
Feb 22, 2023
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We now are recommending customers try CPU Profiling 2.0.
The API currently doesn't return anything; will be implemented in the next commits.
The API still doesn't return anything, but the configuration is correctly propagated all the way to the `CpuAndWallTimeWorker` native code.
**What does this PR do?**: This PR adds a new profiler public API: `Datadog::Profiling.allocation_count`. The public documentation for this API is as follows: > Returns an ever-increasing counter of the number of allocations > observed by the profiler in this thread. > > Note 1: This counter may not start from zero on new threads. It > should only be used to measure how many > allocations have happened between two calls to this API: > ```ruby > allocations_before = Datadog::Profiling.allocation_count > do_some_work() > allocations_after = Datadog::Profiling.allocation_count > puts "Allocations during do_some_work: #{allocations_after - allocations_before}" > ``` > (This is similar to some OS-based time representations.) > > Note 2: All fibers in the same thread will share the same counter > values. > > Only available when the profiler is running, the new CPU Profiling > 2.0 profiler is in use, and allocation-related > features are not disabled via configuration. > For instructions on enabling CPU Profiling 2.0 see the ddtrace > release notes. As long as CPU Profiling 2.0 is in use, this API is enabled by default. To disable it, this PR adds a new setting: ```ruby Datadog.configure do |c| c.profiling.advanced.allocation_counting_enabled = # ... end ``` **Motivation**: This feature has long been something we want to provide with ddtrace, see issues #2164 and #468, as well as PRs #1891, #1805, #597 As part of the ongoing work of enabling allocation profiling, counting the number of allocations comes at a very cheap cost since the profiler needs to have a `RUBY_INTERNAL_EVENT_NEWOBJ` tracepoint anyway -- it's just a matter of also incrementing a counter inside it. **Additional Notes**: Note that this does not yet change any user-visible feature for ddtrace. I'm counting on @marcotc to pick up the task of using this API to make some tracing magic :) **How to test the change?**: This change includes code coverage. --- Fixes #2164
When I wrote the previous expectation, I was assuming that the class never got loaded on unsupported Rubies. Which is true... in production. For tests, we actually have something like ```ruby require 'datadog/profiling/spec_helper' require 'datadog/profiling/collectors/cpu_and_wall_time_worker' RSpec.describe Datadog::Profiling::Collectors::CpuAndWallTimeWorker do before { skip_if_profiling_not_supported(self) } ``` which means that even on Ruby 2.1 or JRuby we still load the class, thus causing CI failures.
These workarounds are similar to the ones we already had for GC profiling.
Unfortuantely on 3.x Rubies it needs to default to false.
github-actions
bot
added
core
Involves Datadog core libraries
profiling
Involves Datadog profiling
labels
Feb 20, 2023
Codecov Report
@@ Coverage Diff @@
## ivoanjo/prof-7251-exclude-disabled-profiling-types #2635 +/- ##
======================================================================================
- Coverage 98.07% 98.07% -0.01%
======================================================================================
Files 1153 1153
Lines 63164 63251 +87
Branches 2813 2819 +6
======================================================================================
+ Hits 61950 62035 +85
- Misses 1214 1216 +2
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
marcotc
approved these changes
Feb 21, 2023
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.
Awesome work! 🙇
Base automatically changed from
ivoanjo/prof-7251-exclude-disabled-profiling-types
to
master
February 22, 2023 10:08
Merged
ivoanjo
added a commit
that referenced
this pull request
Jul 22, 2024
**What does this PR do?** This PR introduces a new setting for the profiler: `profiling.advanced.allocation_counting_enabled` which controls the profiler allocation counting feature. This setting is off by default, enabling us to reduce allocation profiling overhead slightly. **Motivation:** We actually used to have this setting back in the ddtrace 1.x series. We introduced it in #2635 and removed it in #3281 -- by tieing it directly to allocation profiling. I decided to re-introduce it so we can disable this feature by default. **Additional Notes:** This PR sits atop #3797 because it makes sense to measure both overhead improvements together, but is otherwise completely independent. **How to test the change?** Here's the results for running the `profiler_allocation` benchmark: ``` ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux] Warming up -------------------------------------- Allocations (baseline) 1.419M i/100ms Calculating ------------------------------------- Allocations (baseline) 14.535M (± 2.1%) i/s - 146.197M in 10.062717s Warming up -------------------------------------- Allocations (alloc_profiling_enabled) 1.122M i/100ms Calculating ------------------------------------- Allocations (alloc_profiling_enabled) 11.636M (± 2.2%) i/s - 116.679M in 10.032209s Warming up -------------------------------------- Allocations (alloc_profiling_disabled) 1.124M i/100ms Calculating ------------------------------------- Allocations (alloc_profiling_disabled) 11.866M (± 2.6%) i/s - 119.175M in 10.050580s Comparison: Allocations (baseline): 14534979.3 i/s Allocations (alloc_profiling_disabled): 11865926.7 i/s - 1.22x slower Allocations (alloc_profiling_enabled): 11635919.9 i/s - 1.25x slower ``` The difference is close to the margin of error; nevertheless this feature was showing up on the native profiler, and since it was on the hot path for allocation profiling, I think it's worth it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What does this PR do?:
This PR adds a new profiler public API:
Datadog::Profiling.allocation_count
.The public documentation for this API is as follows:
On Ruby 2.x, as long as CPU Profiling 2.0 is in use, this API is enabled by default.
On Ruby 3.x, this API is disabled by default because of a Ractor bug. On Ruby 3 apps that don't use Ractors, this is still safe to enable (via configuration).
To manually enable or disable this feature, this PR adds a new setting:
Motivation:
This feature has long been something we want to provide with ddtrace, see issues #2164 and #468, as well as PRs #1891, #1805, #597.
As part of the ongoing work of enabling allocation profiling, counting the number of allocations comes at a very cheap cost since the profiler needs to have a
RUBY_INTERNAL_EVENT_NEWOBJ
tracepoint anyway -- it's just a matter of also incrementing a counter inside it.Additional Notes:
Note that this does not yet change any user-visible feature for ddtrace. I'm counting on @marcotc to pick up the task of using this API to make some tracing magic :)
This PR is on top of #2634 just for my convenience, but both changes are independent.
How to test the change?:
This change includes code coverage.
Fixes #2164