Repository navigation
Point mass matrix without skew's zero products; box hulls and the block hash - #108
Merged
Merged
Conversation
point_mass_matrix formed skew(r) i skew(r) through two full 3x3 products per body, and GCC called it rather than inlining it: a sixth of the joint grid's samples. It now leaves out the products with skew's zeros. Each surviving term is the one mul_mm forms, added in the same order, and adding an exact zero product changes nothing, so the matrix is the same to the bit; a new test checks that over 2,000 random anchors, masses and inertias. Joint grid, interleaved against main, 4 rounds: solve 3.87-4.23 to 3.09-3.38 ms, relax 3.87-4.22 to 3.01-3.22, step 13.6-14.5 to 11.5-12.7, the same height sum. The solve and relax are now level with Box3D main's (3.33 and 3.22). The motor, revolute and weld joints use the same matrix.
The box hull's topology came from helpers holding their table as a local array, so every call copied the whole table onto the stack (96 calls a box). It is now written out in the builder. hash_bytes ran every word through one chain of multiplies; it now runs four lanes, so the chains overlap. 2,000 box hulls: 2.9 ms to 0.62 (Box3D 0.17). Mesh and height field builds, which hash their blocks too: median mesh 234-260 to 207-224 ms, height field 172-181 to 152-161. hash_bytes reads its words through memcpy (native.load_word): read through an integer pointer, as before, they break C's aliasing rule for blocks written as doubles and structs. Once the hash was inlined, GCC moved the reads ahead of the writes, and the compound benchmark's material table found 253 materials instead of 2. Main's hash has the same latent fault, unseen only because it was not inlined. Writing the topology as tables in the builder instead slowed the compound benchmark's rays by ~6% through GCC's inlining of its main; written out as literals, the rays are where they were.
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.
What
point_mass_matrixformedskew(r) i skew(r)through two full 3x3 products per body. GCC called it instead of inlining it, and the sampling profile (scripts/profile.sh) put 16.5% of the joint grid in it. It now leaves out the products with skew's zeros: about a quarter of the multiplies, and two matrices passed by pointer instead of copied.Results are unchanged
Each surviving term is the one
mul_mmforms, added in the same order, and adding an exact zero product to a finite sum changes nothing. So the matrix is the same to the bit. A new check intests/test_joint_solver.aecompares it with the full product over 2,000 random anchors, masses and inertias, at three scales. Perturbing one term makes the check fail on all 2,000.Measured
Joint grid alone, interleaved against main, 4 rounds, one thread:
e77352cSame height sum. The joint solve and relax are now level with Box3D main's. The motor, revolute and weld joints use the same matrix.
scripts/test.shpasses 28/28 locally on Aether 0.779.0.Also in this PR: box hulls and the block hash
hash_bytesran every word through one serial chain of multiplies; four lanes now overlap. Mesh and height field builds hash their blocks too.hash_bytesnow reads words throughmemcpy(native.load_word). Reading through an integer pointer broke C's aliasing rule for blocks written as doubles and structs. Once the faster hash was inlined, GCC moved the reads ahead of the writes, and the compound benchmark's material table found 253 materials instead of 2. Main has the same latent fault; it stays hidden only because the hash isn't inlined there.tests/test_compound.aegains a two-material, 2,000-child check on the benchmark's scene. In the test program GCC inlines differently, so that check did not fail without the fix; the benchmark is what showed the bug.Holding the tables as local arrays in the builder slowed the compound benchmark's rays by about 6%, through GCC's inlining of its
main. Written out as literals, the rays stay at main's 26.5-27.1 ms. Hashes are only compared within a run (dedup and equality), so changing the hash function changes no stored data's meaning.