Speed up connect_the_chunks for large numbers of chunks - #3266
Conversation
26b174d to
a9223d9
Compare
|
This is a reasonable sort of optimization at first glance, but I'm a little worried about anything that increases the complexity of the code that computes the boundary connections, which is already extremely complicated. How much speedup do real applications get from optimizing this code, which usually only executes once at the beginning of the simulation? |
|
That is the right metric. For a conventional long, one-shot FDTD run, this only removes a fixed startup cost, so the end-to-end benefit may be small. The motivating real application was a 2.2M-voxel 3D adjoint-optimization problem that reconstructs the fields once per iteration. The steady-state timings on a dual EPYC-9554 node were:
Thus, in this repeated-initialization workload, connection construction accounted for 35–82% of the iteration time before the patch and approximately 8–10% afterward. The deployed build reduced the complete iteration time by 40% at 64 ranks and 50% at 128 ranks. The patched-build iteration totals also include automatic caching of the adjoint eigenmode source, so I do not attribute the entire end-to-end reduction to this PR. The connection-setup timings are measured separately and isolate the change in this patch. I agree that the tradeoff is much less compelling for long one-shot simulations. Given the maintenance concern, I can simplify this patch to retain only the conservative candidate-pair pruning if preferred. |
|
Go ahead and see if you can simplify the patch. |
Use the existing one-cell-padded grid volume to prune candidate pairs in the common non-periodic, no-symmetry case, while falling back to the original all-pairs scan otherwise. Skip source chunks whose candidates are all remote-to-remote, but retain the original communication-buffer allocation.
1fa0491 to
df8b3d5
Compare
|
I tested two reduced versions before updating the PR. The first retained only candidate-pair pruning. That preserved most of the I then retained the small I rebuilt all variants from the same
Thus, candidate pruning alone is still 4–5× faster than the baseline, but the In the serial forced-chunk benchmark, candidate pruning alone was within 4% of The numerical Ez probe was exactly identical across all variants and repeats. These absolute timings are from a separate, explicitly core-bound server8 I have force-pushed the reduced version and updated the PR description. |
fields::connect_the_chunks()tests every not-owned boundary point of everychunk against every other chunk, on every process. The expensive point scan
therefore grows as O(num_chunks² × boundary points), and workflows that rebuild
fieldsrepeatedly pay this cost once per iteration.This PR conservatively prunes candidate chunk pairs before the point scan.
The connection tables and per-point
owns()checks are unchanged.What changed
For the common case with no periodic boundaries or symmetry transforms,
chunk_candidates[i]is precomputed by intersecting chunki's existingone-grid-point-padded
grid_volumewith the other chunk volumes. Both pointscans then iterate only over those candidates.
Periodic or symmetry-reduced simulations use the original all-pairs scan.
This avoids adding new periodic-shift or symmetry-transform logic to the
already complicated boundary-connection code.
chunk_needed[i]also skips source chunks whose candidate pairs are allremote-to-remote on the current process. The loop body previously rejected all
of those pairs individually with the same process-locality condition.
Communication-buffer allocation and lifetime are unchanged from
master.Why the pruning is conservative
Without periodic wrapping or symmetry transforms,
locate_component_point()either leaves a boundary point at the same locationor rejects it.
grid_volume::pad()contains the one-cell not-owned halo, so ifthat padded volume does not intersect chunk
j, chunkjcannot own any pointfrom the scan. The existing per-point
owns()test remains the final check, sofalse candidates only cost extra comparisons.
For periodic or symmetry-reduced cases no pair is pruned, so their behavior is
the original behavior.
Measurements
Measured on a dual EPYC 9554 node using the 8×5×4 µm, resolution-24 3D PML
workload (approximately 2.2M voxels). Values are medians of three interleaved
runs with
OMP_NUM_THREADS=1and one MPI rank bound per physical core. Themetric is the maximum-rank wall time for the first
fields::step()afterinit_sim().Serial forced-chunk measurements at resolution 16:
The numerical Ez probe was exactly identical across all variants and repeats.
The pair enumeration remains O(num_chunks²), but the surviving box tests are
much cheaper than repeating the boundary-point scan for every chunk pair.
These measurements are from a separate, explicitly core-bound campaign and
should not be compared directly with absolute timings from the earlier
unbound campaign.