perf: experiment with striped classic histogram accumulator - #2329
perf: experiment with striped classic histogram accumulator#2329zeitlinger wants to merge 10 commits into
Conversation
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
|
1 similar comment
|
Benchmark resultsBenchmark run succeeded for
Prometheus Java Client BenchmarksRun Information
Comparison with base
Results for PR headCounterBenchmark
HistogramBenchmark
HistogramTextFormatBenchmark
TextFormatUtilBenchmark
Raw ResultsNotes
Benchmark Descriptions
|
|
Evaluation (local, JDK 25.0.4, x86_64, 1 fork / 2 warmups / 5 measurements; indicative rather than production benchmark):
Recommendation: use #2329 as the basis, not #2252, but do not merge yet. Please add jcstress/JMM coverage, bound or reclaim retained cells, and define bounded scrape progress/latency when a writer is delayed. Existing focused concurrency tests pass repeatedly, but they do not close those risks. |
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
|
Hardening update: pushed
Focused accumulator/Histogram tests, repeated concurrency tests, benchmark compilation, and formatter/lint pass locally. Full CI benchmark matrix and cross-JDK/architecture validation remain appropriate before merge. |
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
|
Follow-up hardening pushed in
Local focused tests: 5 accumulator tests and 35 Histogram tests pass, with the accumulator suite repeated five times. JMH smoke (JDK 25.0.4, x86_64, 1 fork, 1×100 ms warmup, 2×100 ms measurement, 1,000 short-lived recorders; setup excluded): collect 1,218 ops/s and getCount 1,600 ops/s. These are indicative scan-cost measurements only. The current |
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
|
JCStress evidence added in
The stalled-writer test uses reflection only in the JCStress test module to model a pause at the internal epoch boundary; production code has no test hooks. Cross-JDK/architecture stress coverage remains for CI/maintainer validation. |
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Summary
This is an experimental alternate implementation for benchmarking against
mainand the synchronized candidate in #2252. It is not being presented as production-ready yet.For classic-only histograms, this replaces the existing
Buffer/LongAdderrecording path with an epoch-striped, double-buffered per-thread accumulator. Each recording thread owns a cell, observations update plain thread-confined bucket/count/sum fields, and collection advances a global epoch before draining the inactive buffers. This avoids a globalsynchronized (DataPoint)monitor on the shared four-thread observe path while preserving coherent bucket/count/sum snapshots.getCount()andgetSum()use the same snapshot mechanism.Native-only and hybrid histograms keep their existing implementation. The public API is unchanged.
Local evidence
mise run lint./mvnw -pl prometheus-metrics-core -Dtest=HistogramTest test— 35 tests passed./mvnw -pl prometheus-metrics-core -am verify— reactor passed; core ran 157 testsgit diff --checkHistogramBenchmark.prometheusClassic: 40,944.515 ± 302.666 ops/sThe local JMH number is a smoke result, not a controlled cross-branch conclusion. The
benchmarkworkflow is being requested so this branch andmainare measured on the same runner.Added concurrency coverage
getCount()/getSum()valuesclear()lifecycle behavior for old and newly-created data pointsRemaining hardening before merge consideration
getCount()/getSum(), which currently perform an epoch flip and cell scan to return exact accumulated values.Related: #2252