Repository navigation
Step 1: reuse map-bucket lookups across LM iterations (~1.7x faster, identical results) - #570
Merged
JanuszBedkowski merged 1 commit intoOct 18, 2026
Conversation
Each point's indoor/outdoor bucket was looked up twice per iteration (normal-vector histogram, then Hessian). Now it is looked up once, and after the first iteration only for points whose bucket key changed; the histograms are adjusted for just those points (exact integer counts). optimize_lidar_odometry takes the cached buckets instead of the maps. The maps only change between chunks, on the same thread, so the cached pointers stay valid across iterations. Port of mini_lio d969246. JT128 hand-held session (140 s, default params, Apple M5): 142.2 s -> 87.9 s optimization; all outputs (trajectories, poses, LAZ) byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
michalpelka
marked this pull request as draft
October 17, 2026 23:02
michalpelka
marked this pull request as ready for review
October 18, 2026 06:43
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
In
lidar_odometry_step_1, every LM iteration looked up each point's indoor/outdoor NDT bucket twice: once to build the normal-vector histograms (anisotropic weighting), then again when building the Hessian. Step 1 typically runs ~170–180 iterations per chunk, so these hash lookups made up a large share of the runtime.This PR:
PointBuckets: pointers, keys, histogram bins) across the iterations of a chunk. Each bucket is looked up once per iteration, and after the first iteration only for points whose bucket key changed.optimize_lidar_odometrynow takes the cached buckets instead of the maps. The stale declaration inlidar_odometry_utils.his updated to match.The bucket maps are only modified between chunks (
process_worker_step_update_rgd_after, on the same worker thread), so the cached pointers stay valid. The GUI only reads the maps under the same mutex.Port of the same optimization from mini_lio (header-only port of step 1).
Results: identical output, ~1.6–1.7× faster
Apple M5, Release build. Original =
25bc0ca, patched = this branch..tomlWall time on MandeyeMappingLoopClosure: 782.6 s → 484.3 s; CPU time (user): 4755 s → 2631 s.
How "byte-identical" was checked on MandeyeMappingLoopClosure:
scan_lio_*.laz,trajectory_lio_*.csv,session_poses.mrp,session_ini_poses.mri,point_sizes_per_chunk.json) are identical (cmp).fdd94290…34cd) in both runs.session.mjsdiffers only in elapsed time and output paths. TheHDMapping_*params/results files were skipped because they contain timestamps.Note: both MandeyeMappingLoopClosure runs used
real_time_threshold_seconds = 1e9, with the machine kept awake (caffeinate). That threshold is a wall-clock cutoff, so a stall (e.g. the machine sleeping) truncates a chunk's iterations and makes results timing-dependent. In normal runs, chunks take ~0.1 s and it never fires.Test plan
lidar_odometry_step_1🤖 Generated with Claude Code