perf(engine): implement two-tier browse-resistant MLD path unpacking cache#7540
Open
DennisOSRM wants to merge 6 commits into
Open
perf(engine): implement two-tier browse-resistant MLD path unpacking cache#7540DennisOSRM wants to merge 6 commits into
DennisOSRM wants to merge 6 commits into
Conversation
…cache Closes #3835 Add BrowseResistantCache<K,V> (include/util/browse_resistant_cache.hpp), a two-tier LRU designed to resist sequential-scan ("browse") pollution. New entries are admitted to a probationary tier (L1); a second hit promotes them to a protected tier (L2). L2 evictions demote to L1 rather than being discarded outright, so frequently-used sub-paths survive one-shot sequential traversals. A simple single-tier LRU was evaluated during development but showed no measurable performance advantage over the two-tier design, which also provides better robustness against pathological access patterns. The cache is keyed on (source, target, level, cell_id) and stores the unpacked node and edge sequences for each sub-path resolved during MLD path expansion. It is allocated per thread in SearchEngineData<MLD> and sized at 10% of the estimated graph memory (20% L1 / 80% L2), keeping memory overhead proportional to the graph being served. Integration in routing_base_mld.hpp uses if constexpr to detect cache availability, keeping the path branchless at compile time for algorithms that do not carry a cache. Benchmark results on an M4 Pro (hot cache vs. no cache, times in ms): | Metric | Min | Max | Average | Median | |---------|------|------|---------|--------| | Master | 0.21 | 8.95 | 3.13 | 3.12 | | Cache | 0.22 | 7.76 | 2.46 | 2.48 | | Speedup | — | 1.15 | 1.27× | 1.26× | Also included: - car profile: add priority_penalty (0.7×) for the non-priority direction on roads tagged with priority=forward/backward - way_handlers: apply priority penalty in penalties handler; update taginfo.json - bicycle profile: fix bike-push handler so foot_forward/foot_backward overrides are applied regardless of way_type_allows_pushing Note: the implementation was written by the author; only the commit message and PR description were produced with AI assistance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- browse_resistant_cache: fix insert() to remove duplicate keys from L1/L2 before inserting, preventing orphaned list nodes and counter corruption - browse_resistant_cache: fix get() to re-lookup the key in both tiers after promote()+evict_l2(), guarding against the entry being demoted back to L1 when its cost exceeds the L2 budget - routing_base_mld: guard unpacking_cache dereference with a null check so call paths that skip InitializeUnpackingCache() don't segfault - search_engine_data: track last-seen node/edge counts in the cache's thread- local state; recreate and clear the cache when counts change (e.g., on data reload) instead of blindly reusing a stale budget - profiles/car.lua: fix priority_penalty comment (not narrow-road-specific) - features/car/priority.feature: fix description and scenario name to reflect that the penalty applies to the non-priority direction on oneways too - unit_tests: add duplicate-key insert tests for both L1 and L2 tiers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or 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
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.
Summary
Implements the path unpacking cache proposed in #3835.
During MLD route computation, the recursive
search()function repeatedly unpacks the same sub-paths between partition-cell border nodes at lower hierarchy levels. This PR caches those results so that identical(source, target, level, cell_id)lookups are served from memory instead of triggering a full sub-search.Implementation
BrowseResistantCache<K, V, CostFn>(include/util/browse_resistant_cache.hpp)A new general-purpose two-tier LRU cache resistant to sequential-scan ("browse") pollution:
A simple single-tier LRU was evaluated during development but showed no measurable performance advantage over the two-tier design. The two-tier approach was kept for its better resilience against pathological sequential-access patterns.
MLD unpacking cache (
include/engine/search_engine_data.hpp)(source, target, level, cell_id)—MLDUnpackingCacheKeynodes+edgesvectors —MLDUnpackingCacheValuethread_local UnpackingCachePtr unpacking_cacheinsideSearchEngineData<MLD>Integration (
include/engine/routing_algorithms/routing_base_mld.hpp)Cache lookup and insertion are guarded by
if constexpr (requires { engine_working_data.unpacking_cache; }), so algorithms that do not carry a cache incur zero overhead.Benchmark results
Measured on an M4 Pro CPU, comparing a hot-cache run against master (no cache). Times in milliseconds:
Additional changes in this PR
priority_penalty(0.7×) applied to the non-priority direction on roads tagged withpriority=forwardorpriority=backwardpriority_penaltyin thepenaltieshandler; register the tags intaginfo.jsonfoot_forward/foot_backwardoverrides are applied regardless ofway_type_allows_pushingNotes
The implementation was written by the author. Only the commit message and this PR description were produced with AI assistance.