Commit Graph

4 Commits

Author SHA1 Message Date
Yuval Tassa e6d77650f7 Refactor mju_combineSparse to eliminate temporary buffers.
Combine sparse vectors in-place by first counting total `nnz` and then working backwards from the end. This removes the need for temporary buffers in `mju_combineSparse` and its callers and speeds up the function by ~10%.

PiperOrigin-RevId: 902530210
Change-Id: I4f48c327103552ab968d3915399c6067367bec9f
2026-04-20 03:10:18 -07:00
Yuval Tassa a2d0e33c0f 2-3x speedup of sparse matrix squaring.
Split symbolic and numeric phases for sparse `M'*diag*M` computation. Microseconds per call for the monolithic vs the split approach for the 100_humanoids and 2humanoid100 models:

```
+-------+------+----------+------------+---------+
| Model | Arch | Col (µs) | Split (µs) | Speedup |
+-------+------+----------+------------+---------+
| 2H100 | x86  | 238.3    | 74.5       | 3.2x    |
+-------+------+----------+------------+---------+
|       | ARM  | 111.6    | 53.2       | 2.1x    |
+-------+------+----------+------------+---------+
| 100H  | x86  | 1325.3   | 656.2      | 2.0x    |
+-------+------+----------+------------+---------+
|       | ARM  | 594.8    | 306.6      | 1.9x    |
+-------+------+----------+------------+---------+
```

PiperOrigin-RevId: 900154308
Change-Id: Ia6e9b8e196e2ed37b723a0faf60e9731303a9619
2026-04-15 07:19:41 -07:00
Yuval Tassa 849a650143 Refactor mju_cholUpdateSparse to use a dense accumulator, 1.5-2x function speedup.
PiperOrigin-RevId: 846754379
Change-Id: Ie599658db2907a26095072d97d07b99a693050dc
2025-12-19 08:57:45 -08:00
Yuval Tassa 45b0153067 Refactor sparse Cholesky factorization into symbolic and numeric phases.
The new symbolic function is a generalization of the function it replaces. In this CL it takes two unused temp arrays. The actual change in behavior happens in the followup.

New benchmark test output below ("L" is 2 humanoids and 100 free objects, "XL" is 100 humanoids). Note that `symbolic` is only ever called once per Newton iteration, while `numeric` is sometimes called multiple times (when the rank-1 update fails), hence timing them separately is valuable.

```
Benchmark               Time(ns)        CPU(ns)     Iterations
--------------------------------------------------------------
BM_old_L_mean              84382          84703          19547  11.807k items/s
BM_symbolic_L_mean         16345          16381          88414  61.055k items/s
BM_numeric_L_mean          10986          10994         120000  90.999k items/s
BM_old_XL_mean           1241208        1244212           1200  803.924 items/s
BM_symbolic_XL_mean       130917         131042          12720  7.631k items/s
BM_numeric_XL_mean         77004          76767          21116  13.029k items/s
```

PiperOrigin-RevId: 846704054
Change-Id: Ib0c365724d63bf2b81606ca5353756a6496c3a26
2025-12-19 06:11:55 -08:00