graph LR subgraph iter["Every iteration"] snap["Copy snapshot\nzs_snapshot = zs"] --> tasks["Dispatch N tasks\npool.enqueue()"] tasks --> sync["Join all tasks\nfuture.get()"] sync --> copy["Copy back\nzs = zs_snapshot"] end copy --> check{"Converged?"} check -- "No" --> snap check -- "Yes" --> done["Roots found ✅"] style snap fill:#ffcdd2,stroke:#c62828,stroke-width:3px style tasks fill:#fff3e0,stroke:#e65100,stroke-width:3px style sync fill:#fff3e0,stroke:#e65100,stroke-width:3px style copy fill:#ffcdd2,stroke:#c62828,stroke-width:3px style check fill:#fff9c4,stroke:#f57f17,stroke-width:3px style done fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph LR subgraph cpp["ginger-cpp"] st["aberth\npbairstow_even\npbairstow_autocorr\n(ST)"] mt["aberth_mt\npbairstow_even_mt\npbairstow_autocorr_mt\n(snapshot + barrier)"] at["aberth_atomic\npbairstow_even_atomic\npbairstow_autocorr_atomic\n(atomic buffer)"] st --> mt --> at end subgraph rs["ginger-rs"] rst["aberth\npbairstow_even\npbairstow_autocorr\n(ST)"] rmt["aberth_mt\npbairstow_even_mt\npbairstow_autocorr_mt\n(rayon + snapshot)"] rat["aberth_atomic\npbairstow_even_atomic\npbairstow_autocorr_atomic\n(rayon pool + seqlock)"] rst --> rmt --> rat end style at fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style rat fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph LR subgraph buf["Atomic working buffer — built ONCE"] s0["slot 0"] s1["slot 1"] s2["slot 2"] s3["... slot i ..."] end subgraph thr["Threads"] t0["Thread 0"] t1["Thread 1"] t2["Thread 2"] end t0 -- "store() own slot" --> s0 t0 -. "load() others" .-> s1 t0 -. "load() others" .-> s2 t1 -- "store() own slot" --> s1 t1 -. "load() others" .-> s0 t1 -. "load() others" .-> s2 t2 -- "store() own slot" --> s2 t2 -. "load() others" .-> s0 style t0 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style t1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style t2 fill:#fff3e0,stroke:#e65100,stroke-width:3px style s0 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style s1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style s2 fill:#fff3e0,stroke:#e65100,stroke-width:3px
graph TD spawn["Dispatch N long tasks ONCE"] --> ta["Thread A\nown iteration loop"] spawn --> tb["Thread B\nown iteration loop"] spawn --> tc["Thread C\nown iteration loop"] ta --> ca{"chunk converged?"} tb --> cb{"chunk converged?"} tc --> cc{"chunk converged?"} ca -- "no → iterate" --> ta cb -- "no → iterate" --> tb cc -- "no → iterate" --> tc ca -- "yes → exit" --> join["join all\n(max niter, all converged)"] cb -- "yes → exit" --> join cc -- "yes → exit" --> join style ta fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style tb fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style tc fill:#fff3e0,stroke:#e65100,stroke-width:3px style join fill:#fff9c4,stroke:#f57f17,stroke-width:3px
graph LR subgraph before["Before: everyone starts at slot 0 ⚠️"] a0["Thread 0 → reads 1 2 3 4"] a1["Thread 1 → reads 0 2 3 4"] a2["Thread 2 → reads 0 1 3 4"] end subgraph after["After: round-robin rotation ✅"] b0["Thread 0 → reads 1 2 3 4"] b1["Thread 1 → reads 2 3 4 0"] b2["Thread 2 → reads 3 4 0 1"] end style a0 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style a1 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style a2 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style b0 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style b1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style b2 fill:#fff3e0,stroke:#e65100,stroke-width:3px
sequenceDiagram participant W as Writer (thread i) participant S as Slot (seqlock) participant R as Reader (thread j) W->>S: seq++ (odd) · write re, im R->>S: s1 = seq.load() R->>S: read re, im R->>S: s2 = seq.load() alt s1 == s2 and even R-->>R: torn-free pair ✅ else R-->>R: retry 🔄 end W->>S: seq++ (even) → stable