Use a permanent thread local Calculation object - #363
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📜 Recent review details🔇 Additional comments (3)
WalkthroughThe routing server now reuses a thread-local Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@connection_scan_algorithm/src/transit_routing_http_server.cpp`:
- Around line 153-169: Update getThreadCalculator and the Calculator cleanup
path to account for retained peak routing-buffer memory: add metrics for
per-thread peak allocation and implement an explicit trimming policy, such as
shrinking buffers beyond a defined threshold after reset/clear. If trimming is
intentionally deferred, document enforceable request-size and compute-thread
limits instead, while preserving thread-local reuse for normal requests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d3ae1c29-dcc9-4a0a-8aab-cd265668f69f
📒 Files selected for processing (3)
connection_scan_algorithm/include/calculator.hppconnection_scan_algorithm/src/resets.cppconnection_scan_algorithm/src/transit_routing_http_server.cpp
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
- GitHub Check: pr-build-check
- GitHub Check: Test build on macOS-latest (memcached: false)
- GitHub Check: Test build on macOS-latest (memcached: true)
- GitHub Check: Test build on ubuntu-latest (memcached: false)
- GitHub Check: Test build on ubuntu-latest (memcached: true)
- GitHub Check: Analyze (cpp)
🧰 Additional context used
🪛 Clang (14.0.6)
connection_scan_algorithm/src/transit_routing_http_server.cpp
[warning] 161-161: use a trailing return type for this function
(modernize-use-trailing-return-type)
🪛 Cppcheck (2.21.0)
connection_scan_algorithm/src/resets.cpp
[style] 36-36: The function 'getArrivalTime' is never used.
(unusedFunction)
[style] 37-37: The function 'getTrip' is never used.
(unusedFunction)
[style] 36-36: The function 'accept' is never used.
(unusedFunction)
🔇 Additional comments (4)
connection_scan_algorithm/src/resets.cpp (2)
75-75: LGTM!Also applies to: 110-110
31-37: 🗄️ Data Integrity & IntegrationNo change needed.
Reset flags are only disabled for alternative calculations, with the fastest route calculating fresh, so first requests do not retain prior footpath/filter state.
connection_scan_algorithm/src/transit_routing_http_server.cpp (1)
360-360: LGTM!Also applies to: 408-408, 456-456
connection_scan_algorithm/include/calculator.hpp (1)
80-86: 🎯 Functional CorrectnessNo change needed.
CalculationTime::start()setsstartEpochto the current epoch, sostartRequestTimer()restarts the request-spanning timer as intended.
9e03012 to
1df1bc7
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
| { | ||
| thread_local Calculator calculator(transitData, geoFilter); | ||
| // Start the timer at the beginning of each request. | ||
| // TODO Maybe we should be it out of the calculator |
There was a problem hiding this comment.
This sentence does not make sense: "be it out"
There was a problem hiding this comment.
Je trouve ca étrange que le lapin aille pas vu ça!
| // tasks queued on the compute pool. | ||
| static Calculator & getThreadCalculator(const TransitData &transitData, GeoFilter &geoFilter) | ||
| { | ||
| thread_local Calculator calculator(transitData, geoFilter); |
There was a problem hiding this comment.
C'est le fait que la fonction est statique qui fait que la variable définie comme thread_local à l'intérieur existe durant toute la durée du thread? Je ne connais pas ce keyword... La variable n'est pas définie "globalement/par thread", elle est quand même dans cette fonction après tout.
There was a problem hiding this comment.
https://en.cppreference.com/cpp/language/storage_duration
Thread storage duration
All variables declared with thread_local have thread storage duration.
The storage for these entities lasts for the duration of the thread in which they are created. There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.
Elle est dans la fonction, mais l'objet existe pour toute la durée du thread. C'est un peu comme statique oui, mais pour chaque thread.
One of the main performance issue we have is the memory allocation churn of creating and delete the Calculation object for each request. Instead of always reallocating for each object, we can use a local object for each thread. Since we only have one request at a time being handled on a thread, we don't have concurrency issues. We have to call reset at the start of each request to clear out the data. We also moved the start timer in the request parsing side, instead of doing it the constructor. In local benchmarks we went from calc/sec: 27.37 to calc/sec: 40.4 Duing the genetic algo we went from Batch routing completed: 18973 trips in 33.4s (avg 568.82 calc/sec) to Batch routing completed: 18982 trips in 16.4s (avg 1160.37 calc/sec)
1df1bc7 to
89821b7
Compare
One of the main performance issue we have is the memory allocation churn of creating and delete the Calculation object for each request. Instead of always reallocating for each object, we can use a local object for each thread. Since we only have one request at a time being handled on a thread, we don't have concurrency issues.
We have to call reset at the start of each request to clear out the data.
Summary by CodeRabbit