Skip to content

Add the micro-benchmark for thread filtering - #237

Merged
jbachorik merged 3 commits into
mainfrom
jb/thread_filter_bench
Jul 4, 2025
Merged

Add the micro-benchmark for thread filtering#237
jbachorik merged 3 commits into
mainfrom
jb/thread_filter_bench

Conversation

@jbachorik

Copy link
Copy Markdown
Collaborator

What does this PR do?:
It adds the very limited micro-benchmark for ThreadFilter.addThread/removeThread combination

Motivation:
Reduce the noise in the more 'macro-benchmarky' benchmarks. Allow to focus on the sole performance of adding and removing a thread to the filter with specific parallelism and synthetic workload and see how the performance scales.

Additional Notes:
Running this benchmark on MacBook M1 the difference between the JNI access and Unsafe access is almost non-existent.

We see a huge cliff when going from single thread to more threads when the workload is very low (10-100ns) which seems to be caused by:

  1. Single contended _size variable which is mutated in atomic fashion by all benchmark threads. I tried sharding that variable and collect the actual size only when needed but that improves the situation only marginally and makes it quite difficult to maintain the unsafe implementation.
  2. I tried a more 'random' thread id mapping using golden ration fibonacci hash - but that also provides almost no improvement and makes the unsafe implementation unhappy, as it assumes the original mapping.
  3. There is the only remaining thing

JNI access

BenchmarkWorkloadModeScoreUnits
ThreadFilterBenchmark.threadFilterStress010avgt0.021us/op
ThreadFilterBenchmark.threadFilterStress017avgt0.023us/op
ThreadFilterBenchmark.threadFilterStress0170000avgt147.206us/op
ThreadFilterBenchmark.threadFilterStress020avgt0.143us/op
ThreadFilterBenchmark.threadFilterStress027avgt0.151us/op
ThreadFilterBenchmark.threadFilterStress0270000avgt149.653us/op
ThreadFilterBenchmark.threadFilterStress040avgt0.402us/op
ThreadFilterBenchmark.threadFilterStress047avgt0.449us/op
ThreadFilterBenchmark.threadFilterStress0470000avgt166.627us/op
ThreadFilterBenchmark.threadFilterStress080avgt1.315us/op
ThreadFilterBenchmark.threadFilterStress087avgt1.302us/op
ThreadFilterBenchmark.threadFilterStress0870000avgt167.421us/op
ThreadFilterBenchmark.threadFilterStress160avgt2.783us/op
ThreadFilterBenchmark.threadFilterStress167avgt2.772us/op
ThreadFilterBenchmark.threadFilterStress1670000avgt304.041us/op
ThreadFilterBenchmark.threadFilterStress990avgt15.222us/op
ThreadFilterBenchmark.threadFilterStress997avgt15.599us/op
ThreadFilterBenchmark.threadFilterStress9970000avgt1797.784us/op

Unsafe access

BenchmarkWorkloadModeScoreUnits
ThreadFilterBenchmark.threadFilterStress010avgt0.029us/op
ThreadFilterBenchmark.threadFilterStress017avgt0.032us/op
ThreadFilterBenchmark.threadFilterStress0170000avgt145.954us/op
ThreadFilterBenchmark.threadFilterStress020avgt0.165us/op
ThreadFilterBenchmark.threadFilterStress027avgt0.171us/op
ThreadFilterBenchmark.threadFilterStress0270000avgt150.606us/op
ThreadFilterBenchmark.threadFilterStress040avgt0.497us/op
ThreadFilterBenchmark.threadFilterStress047avgt0.574us/op
ThreadFilterBenchmark.threadFilterStress0470000avgt163.668us/op
ThreadFilterBenchmark.threadFilterStress080avgt1.713us/op
ThreadFilterBenchmark.threadFilterStress087avgt1.690us/op
ThreadFilterBenchmark.threadFilterStress0870000avgt165.619us/op
ThreadFilterBenchmark.threadFilterStress160avgt3.817us/op
ThreadFilterBenchmark.threadFilterStress167avgt3.953us/op
ThreadFilterBenchmark.threadFilterStress1670000avgt303.807us/op
ThreadFilterBenchmark.threadFilterStress990avgt15.862us/op
ThreadFilterBenchmark.threadFilterStress997avgt16.451us/op
ThreadFilterBenchmark.threadFilterStress9970000avgt1788.177us/op

Unsure? Have a question? Request a review!

@Param({"0", "7", "70000"})
public String workload;

private long workloadNum = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Code Quality Violation

Suggested change
privatelongworkloadNum = 0;
privatelongworkloadNum;
Remove initialization, this is already the default value. (...read more)

When initializing fields, prevent initializing fields to the default value. Any additional initialization means more bytecode instructions, and allocating many of these objects may impact your application performance.

If you initialize to a default value, remove the initialization.

View in DatadogLeave us feedbackDocumentation

@github-actions

Copy link
Copy Markdown
Contributor

🔧 Report generated by pr-comment-cppcheck

CppCheck Report

Errors (2)

Warnings (4)

Style Violations (297)

@github-actions

Copy link
Copy Markdown
Contributor

🔧 Report generated by pr-comment-scanbuild

@r1violletr1viollet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jbachorik
jbachorik merged commit a358978 into mainJul 4, 2025
95 checks passed
@jbachorik
jbachorik deleted the jb/thread_filter_bench branch July 4, 2025 12:30
@github-actionsgithub-actionsBot added this to the 1.29.0 milestone Jul 4, 2025
zhengyu123 pushed a commit that referenced this pull request Jul 9, 2025
* Add the micro-benchmark for thread filtering
* Do not test for obviously invalid thread id
* Relax threadfilter mem order
zhengyu123 added a commit that referenced this pull request Jul 9, 2025
* Potential memory leak with the JVMTI wallclock sampler
* v1
* Don't sample terminated thread
* v2
* v3
* v4
* Safe access
* Fix thread state
* v5
* Cleanup
* Cleanup
* safeFetch impl
* jdk11 support
* v6
* enhance and cleanup
* fix nullptr deference
* More cleanup
* Erwan's finding
* Fixed memory leak found by Erwan
* [Automated] Bump dev version to 1.29.0
* Update the sonatype repos (#235)
* Fix artifact download URL
* Split debug (#233)
* Split debug
Add build steps to store split debug information for release builds
* Add the micro-benchmark for thread filtering (#237)
* Add the micro-benchmark for thread filtering
* Do not test for obviously invalid thread id
* Relax threadfilter mem order
* Flaky test - j9 OSR (#239)
Skip zing and j9 flaky tests
* Fix flaky allocation test (#241)
Lower threshold for allocation test
* jbachorik's comments
* More jbachorik's comments
* Cleanup thread local references
---------
Co-authored-by: zhengyu.gu <zhengyu.gu@servicenow.com>
Co-authored-by: Datadog Java Profiler <java-profiler@datadoghq.com>
Co-authored-by: Jaroslav Bachorik <jaroslav.bachorik@datadoghq.com>
Co-authored-by: Jaroslav Bachorik <j.bachorik@gmail.com>
Co-authored-by: r1viollet <74836499+r1viollet@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jbachorik@r1viollet