You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Large pyramid 1.2x, many pyramids 1.15x, mixed pile 1.26x Box3D e77352c; the rest waits on aether#2550 #121
bench/soak.ae vs bench/soak_box3d.c (2,048 boxes/spheres/capsules/random hulls in a walled pen, 600 steps, same dice, one thread, sleep off):
phase, ms/step
Box3D
aephysics
ratio
step
2.78-2.87
3.23-3.49
1.14-1.22
pairs
0.075
0.104
1.38
collide
0.563
0.679
1.21
solve (constraints)
2.14 (1.98)
2.45 (2.24)
1.14 (1.13)
transforms
0.154
0.198
1.28
The constraints share overlaps #96/#95 (eight lanes, float body states). The pairs, the narrow phase of the mixed pairings (capsule/sphere/hull against hull) and finalize's transforms are gaps of their own, not seen on the cube benchmarks. Next: sample-profile the awake run per phase against the reference's profile.
Correction: the Box3D side of the first table was the old pin f555ee4. The local reference/ had never moved to e77352c; fetch_references.sh now fetches when the pin is missing (#124). Against e77352c, with its AVX2 dispatch, the gap is bigger:
awake, ms/step
Box3D e77352c
aephysics (8 lanes, AVX2)
step
2.26-2.43
3.49-3.93
pairs
0.08
0.12
collide
0.53-0.58
0.89-0.93
solve (constraints)
1.64-1.76 (1.42-1.52)
2.49-2.88 (2.22-2.61)
transforms
0.21-0.23
0.25
So 1.5-1.7x awake. The solve share is now mostly the body-state gather/scatter in doubles (#95). Collide is 1.6-1.7x and is the next largest gap of its own.
changed the title [-]Mixed pile: 1.14-1.22x the reference awake, spread over every phase[/-][+]Mixed pile: 1.5-1.7x Box3D e77352c awake, spread over every phase[/+]on Oct 7, 2026
Progress: #126 (float body states) and #127 (float manifolds and contact caches, Box3D's layouts) are merged. On the many-pyramids scene with AVX2: collide 5.7-6.4 to 4.0-4.5 ms, prepare 3.6-3.8 to 2.5-2.8, store 1.7-1.9 to 1.2-1.4.
Still larger than Box3D's: BodySim (424 bytes vs 216; its inertias are doubles), WorldShape (456 vs 208), Body (192 vs 136). Recycling reads two sims and two shapes per contact. Those are next, starting with the inertia matrices and the fat AABBs.
Progress: #133 puts the shape's fat box in its first cache line (collide on the many pyramids 3.05-3.29 to 2.81-3.12 ms).
Where the rest stands against Box3D e77352c on the large pyramid (AVX2, quiet machine):
Prepare and velocity integration are now within 10%.
Warm start, solve and relax (0.76/1.2/1.3 vs 0.60/0.98/1.06 ms): most of the gap is gathering bodies into lanes. Box3D does it with an 8x8 register transpose, and Aether's std.lanes has no shuffle or transpose: aether#2550. That gets picked up the release it ships.
Collide (about 1.2 vs 0.95 ms): next, the contact record (256 vs 216 bytes) and the body record (192 vs 136).
Measured on main (315ed6b), large pyramid, AVX2, best of 5, ms/step, ours against Box3D e77352c: relax 1.35/1.04, solve 1.23/0.95, collide 1.13/0.90, warm start 0.78/0.58, prepare 0.76/0.61, pairs 0.32/0.22, integrate velocities 0.62/0.57, integrate positions 0.16/0.11, store 0.45/0.41.
Relax, solve and warm start (0.8 ms of the gap) are the per-body gather into lanes. That waits on aether#2550.
Tried and dropped: running the recycling test in float, as Box3D does (it widened about 40 values per contact). Pinned best of 10 came out 7.22 against 7.16 ms, no gain, and it would change the golden for nothing. Collide's gap is memory access, not arithmetic.
Pairs phase (0.32 vs 0.22 ms on the large pyramid): our tree nodes are 56 bytes against Box3D's 32, because the bounds are double. The traversal, refit and rebuild stream nodes, so they carry about 1.75 times the bytes.
The double bounds are deliberate. test_large_world steps the same scene 10,000 km from the origin, where a float bound's step is about a metre and the tree would stop culling. Box3D's float tree doesn't support that range. That 0.1 ms is the price of the large-world support and stays, unless a float tree relative to a per-world origin (rebased when bodies move far) can keep both. That would be a design change worth its own issue if the pairs phase ever matters more than 1.4% of the step.
changed the title [-]Mixed pile: 1.5-1.7x Box3D e77352c awake, spread over every phase[/-][+]Mixed pile 1.26-1.29x Box3D e77352c awake (from 1.5-1.7x); most of the rest waits on aether#2550[/+]on Oct 8, 2026
#137: the joint grid is at 1.05x Box3D e77352c (10.78 against 10.21 ms per step, pinned, best of 8; from 11.23). JointSim keeps the inertias in float, as the body sims do, and the spherical joint's warm start skips its angular sum when no spring, motor or limit is on; neither moves a bit. What is left on the grid is the double arithmetic over float records (bench/RESULTS.md, "The joint grid's warm start"). The rest of this issue still waits on aether#2550.
changed the title [-]Mixed pile 1.26-1.29x Box3D e77352c awake (from 1.5-1.7x); most of the rest waits on aether#2550[/-][+]Large pyramid 1.2x, many pyramids 1.15x, mixed pile 1.26x Box3D e77352c; the rest waits on aether#2550[/+]on Oct 9, 2026
#140 ports the reference's encoded body sims on the contact and its dense fat boxes. Collide is level with Box3D on the large pyramid (0.81-0.85 against 0.81-0.94 ms) and ahead on the many pyramids (1.81-1.97 against 1.97-2.36); the scenes stand at 1.2x, 1.15x and 1.05x, the mixed pile at 1.26x (its collide 0.52 against 0.43, more contacts making manifolds afresh in double). Left: the lanes (warm start, solve, relax) on aether#2550, the prepare, and the pairs' double tree kept for large worlds.
The pairs half of this is done in #159. The tree and fat boxes are single precision, rounded outward, and candidates are batched with the pair-set slots prefetched. The pairs phase is 1.44 ms against Box3D's 1.24 on the convex pile, 2.21 against 2.00 on the junkyard and 2.21 against 1.83 on the washer; it was 1.45-1.6x. What remains here is the collide pass's lanes gather, which waits on aether#2550 as before.
Activity
Soak test and mixed-pile bench against the reference (#123)
nicolas-maman commentedon Oct 7, 2026
Correction: the Box3D side of the first table was the old pin
f555ee4. The localreference/had never moved toe77352c;fetch_references.shnow fetches when the pin is missing (#124). Againste77352c, with its AVX2 dispatch, the gap is bigger:So 1.5-1.7x awake. The solve share is now mostly the body-state gather/scatter in doubles (#95). Collide is 1.6-1.7x and is the next largest gap of its own.
[-]Mixed pile: 1.14-1.22x the reference awake, spread over every phase[/-][+]Mixed pile: 1.5-1.7x Box3D e77352c awake, spread over every phase[/+]Eight-lane wide contact solver on f32x8 (#96); references at e77352c (#…
Manifolds and contact caches in float, as the reference's (#121, #37) (…
nicolas-maman commentedon Oct 7, 2026
Progress: #126 (float body states) and #127 (float manifolds and contact caches, Box3D's layouts) are merged. On the many-pyramids scene with AVX2: collide 5.7-6.4 to 4.0-4.5 ms, prepare 3.6-3.8 to 2.5-2.8, store 1.7-1.9 to 1.2-1.4.
Still larger than Box3D's:
BodySim(424 bytes vs 216; its inertias are doubles),WorldShape(456 vs 208),Body(192 vs 136). Recycling reads two sims and two shapes per contact. Those are next, starting with the inertia matrices and the fat AABBs.Body sims in float beside their double positions (#121, #37) (#128)
nicolas-maman commentedon Oct 8, 2026
Progress: #133 puts the shape's fat box in its first cache line (collide on the many pyramids 3.05-3.29 to 2.81-3.12 ms).
Where the rest stands against Box3D e77352c on the large pyramid (AVX2, quiet machine):
std.laneshas no shuffle or transpose: aether#2550. That gets picked up the release it ships.The shape's fat box beside its id and body, one cache line for the co…
Body and contact: what the collide pass reads first (#121, #37) (#136)
nicolas-maman commentedon Oct 8, 2026
Measured on main (315ed6b), large pyramid, AVX2, best of 5, ms/step, ours against Box3D e77352c: relax 1.35/1.04, solve 1.23/0.95, collide 1.13/0.90, warm start 0.78/0.58, prepare 0.76/0.61, pairs 0.32/0.22, integrate velocities 0.62/0.57, integrate positions 0.16/0.11, store 0.45/0.41.
Next: the pairs phase (0.10 ms, 45% over Box3D).
nicolas-maman commentedon Oct 8, 2026
Pairs phase (0.32 vs 0.22 ms on the large pyramid): our tree nodes are 56 bytes against Box3D's 32, because the bounds are double. The traversal, refit and rebuild stream nodes, so they carry about 1.75 times the bytes.
The double bounds are deliberate. test_large_world steps the same scene 10,000 km from the origin, where a float bound's step is about a metre and the tree would stop culling. Box3D's float tree doesn't support that range. That 0.1 ms is the price of the large-world support and stays, unless a float tree relative to a per-world origin (rebased when bodies move far) can keep both. That would be a design change worth its own issue if the pairs phase ever matters more than 1.4% of the step.
[-]Mixed pile: 1.5-1.7x Box3D e77352c awake, spread over every phase[/-][+]Mixed pile 1.26-1.29x Box3D e77352c awake (from 1.5-1.7x); most of the rest waits on aether#2550[/+]Joint grid at 1.05x Box3D: float joint inertias, the warm start skips…
nicolas-maman commentedon Oct 8, 2026
#137: the joint grid is at 1.05x Box3D e77352c (10.78 against 10.21 ms per step, pinned, best of 8; from 11.23). JointSim keeps the inertias in float, as the body sims do, and the spherical joint's warm start skips its angular sum when no spring, motor or limit is on; neither moves a bit. What is left on the grid is the double arithmetic over float records (bench/RESULTS.md, "The joint grid's warm start"). The rest of this issue still waits on aether#2550.
Collide as the reference keeps it: encoded body sims on the contact, …
[-]Mixed pile 1.26-1.29x Box3D e77352c awake (from 1.5-1.7x); most of the rest waits on aether#2550[/-][+]Large pyramid 1.2x, many pyramids 1.15x, mixed pile 1.26x Box3D e77352c; the rest waits on aether#2550[/+]nicolas-maman commentedon Oct 9, 2026
#140 ports the reference's encoded body sims on the contact and its dense fat boxes. Collide is level with Box3D on the large pyramid (0.81-0.85 against 0.81-0.94 ms) and ahead on the many pyramids (1.81-1.97 against 1.97-2.36); the scenes stand at 1.2x, 1.15x and 1.05x, the mixed pile at 1.26x (its collide 0.52 against 0.43, more contacts making manifolds afresh in double). Left: the lanes (warm start, solve, relax) on aether#2550, the prepare, and the pairs' double tree kept for large worlds.
nicolas-maman commentedon Oct 9, 2026
The pairs half of this is done in #159. The tree and fat boxes are single precision, rounded outward, and candidates are batched with the pair-set slots prefetched. The pairs phase is 1.44 ms against Box3D's 1.24 on the convex pile, 2.21 against 2.00 on the junkyard and 2.21 against 1.83 on the washer; it was 1.45-1.6x. What remains here is the collide pass's lanes gather, which waits on aether#2550 as before.