Paper · published

CPU/GPU Simulation Has a Workload Crossover

CPU/GPU simulation routing is workload-shaped: tiny real TennisAgent sensor-state kernels stay CPU-favorable, generic articulated scenes cross on desktop RTX 3090 near practical batch sizes, and a measured-pose single-serve articulated alignment sweep crosses on desktop between batch 512 and 2,048 while z13 ROCm remains CPU-favorable by batch 8,192. Measured-pose and three-repeat variance gates are closed.

Canonical source: docs/CPU_GPU_SIMULATION_CROSSOVER.md

Status: published Date: 2026-08-25 Project: Bulkhead τ / Bulkhead Tau Paper group: Sensor-to-Simulation Engineering Publication posture: frozen and published. The benchmark evidence includes cached MediaPipe landmarks from the single-serve video and a three-repeat variance pass on both desktop and z13.

Abstract

GPU simulation is not automatically faster than CPU simulation. The useful engineering rule is workload-shaped: use CPU for small or latency-sensitive simulation batches, and use GPU only after the target scene has enough independent work to amortize accelerator overhead.

This paper reports three progressively more realistic MuJoCo/MJX measurements. A tiny sensor-state kernel built from real TennisAgent IMU windows does not cross over on either a dual-RTX-3090 desktop or a Ryzen AI MAX 390 / Radeon 8050S laptop. A larger articulated generic scene reaches practical desktop crossover near batch 512 and approaches parity on the laptop by batch 4,096. A single-serve articulated TennisAgent workload, built from one real serve video template and one real Zepp origins stream, reaches desktop crossover between batch 512 and 2,048 while still not crossing over on the laptop by batch 8,192.

The result is not "GPU good" or "CPU good." It is a routing rule:

CPU is the default for small simulations. GPU becomes useful when the workload

is both sufficiently articulated and sufficiently batched for the specific

hardware path.

1. Question

When does CPU MuJoCo stop being the better substrate, and when does batched MJX GPU execution become worthwhile?

The question matters for Bulkhead τ because sensor and hardware-in-the-loop workloads are not homogeneous. Some paths are firmware-fidelity controls, some are tiny sensor transforms, and some are large hypothesis sweeps over simulated states. Treating all of them as "GPU work" would overstate the accelerator's role. Treating all of them as "CPU work" would miss the point where large parallel sweeps become cheaper on the GPU.

2. Hardware and Backends

MachineCPU/GPU pathNotes
Desktopnative MuJoCo CPU; MJX on CUDA cuda:0 / cuda:1dual RTX 3090 available; rows are separate device measurements, not a combined two-GPU speedup
z13native MuJoCo CPU; MJX on ROCm rocm:0Ryzen AI MAX 390 / Radeon 8050S unified-memory path via side-by-side ROCm 7.2.4 userspace

All runners report native CPU rows and MJX rows at matched batch sizes. JIT warm-up is excluded from steady-state timing. GPU rows are only treated as GPU evidence when JAX reports an actual CUDA or ROCm device.

3. Evidence Packets

Primary evidence lives under:

docs/domain_runs/MUJOCO-CPU-MJX-SCALE-001/

Key artifacts:

The summary plot is here:

docs/domain_runs/MUJOCO-CPU-MJX-SCALE-001/single_serve_posefit_variance_plot.png

Measured-pose single-serve workload variance pass

4. Result 1 — Large Generic Articulated Scene

The large generic scene is a 10-joint articulated MuJoCo model. It is not a TennisAgent domain model, but it establishes the basic scaling behavior: scene complexity and batch size determine whether GPU launch and synchronization overhead are amortized.

Desktop RTX 3090

BatchNative CPURTX 3090 GPU 0RTX 3090 GPU 1Reading
256166,121110,417107,786CPU leads
512166,458169,128166,988practical parity
1,024160,500253,316257,943GPU leads
2,048151,117293,124304,164GPU leads
4,096150,989334,735330,209GPU leads ~2.2x

Evidence: desktop_3090_large_verified.json.

z13 unified Radeon path

On the z13, the same large scene approached crossover but did not beat CPU in the tested range. At batch 4,096, CPU measured 164,665 steps/s and the Radeon measured 161,247 steps/s: only a 1.02x CPU advantage.

Evidence: z13_rocm7_large4096_2026-08-24.json.

5. Result 2 — Real TennisAgent Sensor-State Kernel

The first TennisAgent adapter intentionally stayed conservative. It used real Zepp and Apple Watch IMU windows, kept the sensor lanes separate, and reported LabWired only as a firmware-fidelity control. Each real IMU sample initialized a free-body state with:

qvel = [accel * dt linear-velocity proxy, measured gyro]

This representation is honest, but too small to make the GPU useful.

Desktop result

At batch 256, native CPU remained far ahead:

LaneCPUBest MJX GPUReading
Zepp~561k~40kCPU wins
Apple Watch~562k~44kCPU wins

Evidence: tennis_sensor_adapter.json.

z13 result

At batch 256, CPU also led on z13; Apple Watch batch 512 narrowed but did not cross:

Lane / batchCPUMJX GPUReading
Zepp / 256~711k~199kCPU wins
Apple Watch / 256~710k~216kCPU wins
Apple Watch / 512~704k~309kCPU wins

Evidence: z13_tennis_sensor_adapter.json.

6. Result 3 — Single-Serve Articulated Skeleton/Sensor Workload

The heavier TennisAgent workload is closer to an actual application. It uses the existing real serve video:

domains/SensorAgents/TennisAgent/data/golden_sessions/serves_20260103/IMG_0050.MOV

and the real Zepp origins stream for swing 1767490069922 from the plugged-in phone pull / local Zepp database. The model is a 10-actuator torso/arm/racket chain. The batch dimension is not fake duplicated swings; it is a deterministic calibration sweep over one serve:

The template now uses cached MediaPipe pose landmarks from the actual serve window. The conversion is intentionally simple: 2D shoulder/elbow/wrist angles become arm/racket joint targets. This closes the measured-skeleton-fit gate, but it remains a 2D pose-derived alignment workload rather than validated 3D biomechanics.

Desktop RTX 3090 result

The desktop crossed over between batch 512 and 2,048.

BatchCPUBest CUDA MJXGPU / CPU
512~100k~28k0.28x
2,048~97k~112k1.16x
4,096~95k~145k1.52x
8,192~96k~171k1.79x

Evidence: single_serve_skeleton_sensor_desktop.json.

A three-repeat variance pass on the measured-pose workload preserved the same routing decision. Mean throughput over repeats:

BatchCPU meanBest CUDA meanGPU / CPU mean
512~102k~29k0.29x
2,048~96k~104k1.08x
4,096~94k~140k1.49x
8,192~95k~168k1.76x

Evidence: single_serve_posefit_variance_desktop_summary.json and repeat files single_serve_posefit_variance_desktop_r1.json through r3.json.

z13 ROCm result

The z13 did not cross over in the tested range.

BatchCPUROCm MJXGPU / CPU
512~164k~38k0.23x
2,048~105k~63k0.59x
4,096~96k~69k0.72x
8,192~74k~62k0.83x

Evidence: single_serve_skeleton_sensor_z13.json.

The z13 three-repeat variance pass also preserved the routing decision. Mean throughput over repeats:

BatchCPU meanROCm MJX meanGPU / CPU mean
512~182k~36k0.20x
2,048~100k~60k0.61x
4,096~82k~68k0.84x
8,192~76k~63k0.84x

Evidence: single_serve_posefit_variance_z13_summary.json and repeat files single_serve_posefit_variance_z13_r1.json through r3.json.

This does not mean the z13 GPU path is broken. It means the laptop CPU is strong and the integrated GPU/ROCm path does not beat it for this workload by batch 8,192. The desktop result is different because the RTX 3090 has enough raw parallel throughput to pass its CPU once the articulated workload is large enough.

7. Interpretation

The three measurements form a useful ladder:

WorkloadDesktop resultz13 resultMeaning
Tiny real sensor-state kernelno crossover by batch 256no crossover by batch 512CPU default for small sensor transforms
Large generic articulated scenecrossover near batch 512near parity at batch 4,096articulation and batching matter
Single-serve measured-pose articulated alignment sweepcrossover between batch 512 and 2,048no crossover by batch 8,192application-shaped workload crosses on discrete GPU, not unified iGPU

The CPU comparison is also informative. In the single-serve workload the z13 CPU is not weak; it is faster than the desktop CPU at most batch sizes. The desktop crossover is therefore not explained by a weak CPU baseline. It is explained by the RTX 3090 GPU path becoming worthwhile once the batch is large enough.

8. Boundaries

This paper does not claim:

The claim binds to the named runners, artifacts, machines, batch sizes, and workload representations. The TennisAgent single-serve workload is a bridge from synthetic scaling to application-shaped scaling, not a finished digital twin.

9. Engineering Rule

Use this routing rule in Bulkhead τ:

  1. Run small or latency-sensitive sensor transforms on CPU.
  2. Keep LabWired on its firmware-fidelity path; do not relabel it as GPU work.
  3. Use GPU for large parallel articulated sweeps only after a measured crossover exists for the target scene and hardware.
  4. Treat desktop RTX 3090 and z13 unified Radeon as different routing targets; a crossover on one does not imply crossover on the other.

10. Publication State

The two active-draft gates are closed:

Optional future extensions remain:

Those extensions would widen the claim. They are not required for the bounded routing rule published here.

Published as part of the Bulkhead τ release line. Paper inventory: /papers/.