Repository navigation
perf(dem): the planner terrain fills its tiles on every core and decodes two rows of GLO-30 squares at a time - #2739
Merged
Conversation
…des two rows of GLO-30 squares at a time `terrarium::write` sweeps from north to south over the pixel rows of all zooms. The sweep decodes the GLO-30 squares that the northmost pending pixel row needs and drops all other squares, so at most two rows of squares are in memory. A row of tiles fills and encodes on every core. The finished tiles wait in an unlinked spool file beside the output, and the MBTiles takes them zoom by zoom in the old order, so the bytes do not change. `Terrain::open` hashes the GLO-30 files in parallel with a streamed hash and decodes nothing. `Terrain::load` decodes the squares of a latitude range, and `Terrain::height` reads them through `&self` with a per-caller `Recent` cache of reference tiles. The memo of `DemMosaic` is per thread, so threads share one mosaic. The route build loads all squares, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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 |
…test pins the band at a degree line - `Terrain::open` checks the header of each GLO-30 file with `DemTile::check` while it hashes it, so a file that is not a DEM tile stops the bake before the sweep or the OSM import. - `Terrain::height` asserts in debug builds that the squares of its latitude are decoded. - The sweep prints the latitude of each row of squares it decodes. - A test decodes the squares of each band across 47° N and compares every height with those of a terrain that decoded all squares. Without the slack of `squares`, it fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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
planner/terrainnow fills its tiles on every core and keeps at most two rows of GLO-30 squares decoded. Before, it ran on one thread and decoded all squares at the start.terrarium::writegoes from north to south over the pixel rows of all 13 zooms. The northmost pending pixel row selects the squares to decode, and the sweep drops all other squares. No pending row needs a square north of the squares in memory, so each square decodes once.terrain.mbtileson the disk of its output for a short time: about 10.7 GB for DACH.Terrain::openhashes the GLO-30 files with the streamedhash_fileof the store, in parallel, and decodes nothing. It checks the header of each file withDemTile::check, so a file that is not a DEM tile stops the step before the sweep, and the route build before its OSM import.Terrain::heightasserts in debug builds that the squares of its latitude are decoded.Terrain::load(lats)decodes the squares of a latitude range and drops the others.Terrain::heightreads through&selfwith a per-callerRecentcache of reference tiles.DemMosaickeeps its lookup memo per thread, so threads can share one mosaic. The memo cannot change an answer.tiles_inandstep::glo30return theTileIdof each file.planner-router-buildcallsloadfor all squares, so its memory and output do not change.rayonis optional undergeotiff, because the parallel work is the GLO-30 decode. The workspace has norayonentry;obc-bake,obc-drawandobc-pbfalso declarerayon = "1".Why
On the DACH bake of 2026-10-17 (
runs/2026-10-17-071235),planner/terrainused 592 s of CPU in 604 s of wall time for 34,271 tiles. Its peak was 6.75 GB: 136 GLO-30 squares decoded asf32at the same time.Estimate, not measured on DACH. CPU time stays at about 592 s, so 12 cores give about 60 s. Two rows of about 13 squares are about 1.4 GB, and the open tile rows of all zooms about 0.3 GB.
This is the terrain part of the bake system review.
Tests
Byte check. The develop binary and this binary baked the same boxes from GLO-30 squares of the store. The archives have the same SHA-256. The new binary ran with
RAYON_NUM_THREADS=4.d0d5ea65…eb27ce0b…2ff449d3…e95b7a28…With one thread, the 321-tile box used 6.3 s to 6.7 s of CPU in both binaries.
tests/planner.rswrites the last posts of N46E008 and the first of N47E008 at the GLO-30 posting. From north to south across 47° N, a terrain that decodes onlysquares(lat)gives the same height as a terrain that decoded all squares. With no slack insquares, the test fails at 47.000269° N.d0d5ea65…,e95b7a28…).obc test -p obc-dem: 49 passed, 2 skipped (fixture tests).obc suites check: OK.planner_terrainfixture test (--features external-fixtures,terrarium), with theassistant-terrainsquare linked from the store (same SHA-256): passed.obc test -p planner-router-build: 65 passed.cargo clippy -D warningsonobc-dem(default andterrariumfeatures) andplanner-router-build: clean.check_dependencies.pyandprose.py --check: pass. Not run:gen-third-party.sh --check(nocargo-abouthere);rayonis already in the lockfile.Not run: a real terrain bake, because the machine runs other work.
Public docs: no change.
Requirements: none
🤖 Generated with Claude Code