mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-17 04:39:54 +02:00
N is the whole algo-side Photomerge pipeline on 3 × 8 MP photos (register at the engine's scale with the Auto layout, gain + vignette fit, seams, multi-band blend), 16 threads: 1042 ms before, 264 ms after, 3.9×, rounded to 4×. The engine's own glue (reading regions, building weights, writing layers) is not in this number. Registration and multi-band blending ran almost entirely on one thread per image (four images on 16 threads), so most of the machine sat idle. Every output is bit for bit what the serial code produced: a probe that hashes the public Photomerge entry points (detect_many, match_pairs, align for every layout, photometric, seam_labels, multiband at 1 to 7 levels with 1 and 3 channels, with holes in the alpha, with images sticking out of the canvas, plus direct harris / describe calls) matches on all 349 outputs before and after, on 4 × 2 MP, 3 × 8 MP, 97×61, 211×157, 333×251, 320×240 two-image and 40×35 sets, at 16, 3 and 1 threads. - features `blur` (Harris window and BRIEF smoothing): the row pass runs rows in parallel; the column pass cuts the image into bands of 64 columns, each holding the `&mut` row segments of its own columns (no unsafe), run in parallel. Every column keeps its own f32 running sum, started from its first window summed in order and updated in the same order, so only the loop nest changes. - `harris`: Sobel, the corner response and the non-maximum scan are parallel by rows (the candidates are fully ordered by score, y, x afterwards, so arrival order is irrelevant). `describe`: one descriptor per corner in parallel, kept in corner order. - `reduce`, `expand`, `push_pull`: per-row maps in parallel. `reduce`'s column pass adds five whole rows in tap order (same per-element sum, now vectorised); `expand` works out its source columns once and truncates instead of calling libm `floor` (the clamped position is never negative); `push_pull` builds each coarse row from its two fine rows in raster order, which is the order the serial scatter-add used. - `multiband`: grid fill per image, Laplacian difference, band accumulation (every row walks the bands in the original order), normalisation, collapse and the coverage union are parallel. Float additions are never reordered. Left serial on purpose: the peak fold in `harris` (about 1 ms, an order-free max but not worth the proof), the corner spacing grid, `seam_labels` (a dynamic-programming path whose rows depend on the previous one), `photometric` sample gathering, and the pyramid levels themselves (each level needs the one above). Median of 5 (8 MP rows: 7), release, ms, interleaved before/after runs. The laptop was busy with unrelated builds the whole time (load average 11 to 18 on 16 threads), so the 1-thread rows are noisy (a single thread is time-sliced against them) and rows can move by 10 to 20 percent. | Case (probe) | before (16 thr) | after (16 thr) | speedup | before (1 thr) | after (1 thr) | |--------------------------------|----------------:|---------------:|--------:|---------------:|--------------:| | register, 4 × 2 MP | 154 | 60 | 2.6× | 336 | 167 | | multiband, 4 × 2 MP, 3 ch | 407 | 108 | 3.8× | 591 | 407 | | multiband, 4 × 2 MP, 1 ch | 307 | 73 | 4.2× | 813 | 566 | | whole pipeline, 4 × 2 MP | 437 | 160 | 2.7× | 716 | 504 | | register, 3 × 8 MP (full size) | 327 | 124 | 2.6× | 978 | 391 | | multiband, 3 × 8 MP, 3 ch | 2348 | 916 | 2.6× | 1742 | 1150 | | whole pipeline, 3 × 8 MP | 1042 | 264 | 3.9× | 2264 | 1280 | The 8 MP multiband row at 16 threads is the noisiest (minimum of 7: 959 to 224 ms, 4.3×); the whole-pipeline row is steady. Max RSS for the 3 × 8 MP whole pipeline (the probe's inputs are about 1.05 GB of it): 2.79 GB before, 2.79 GB after (three runs each). Tests: the serial `blur`, `reduce`, `expand`, `push_pull` and `multiband` are kept in the test modules as references and compared bit for bit over sizes that cross every band and row boundary (1×1, 1-wide, 1-high, odd sizes, 63 / 64 / 65 / 129 columns, radius 0 to wider than the image, holes, partial and zero weights, ROIs outside the canvas, 1 to 7 levels). Hard-coded hashes recorded from the old code cover multiband, push_pull, reduce + expand everywhere (plain f32 arithmetic), and harris + describe on Linux x86-64 (they go through the platform's hypot / ln / cos / atan2 / sin_cos). Claude-Session: https://claude.ai/code/session_01AfRHB1wHUjrJx6agBYGnVu Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| affinity | ||
| algo | ||
| automation | ||
| cms | ||
| codecs | ||
| color | ||
| compose | ||
| doc | ||
| engine | ||
| format | ||
| geom | ||
| gpu | ||
| heif | ||
| io | ||
| ops | ||
| paint | ||
| plugins | ||
| psd | ||
| raster | ||
| raw | ||
| tablet | ||
| testkit | ||
| text | ||
| ui-egui | ||
| vector | ||