Section 17.6: Throughput, wall-clock, and cost engineering

"A million frames per second means nothing if they all arrive after the budget is gone."

A GPU Cluster Invoice
Illustration for Section 17.6: Throughput, wall-clock, and cost engineering
Figure 17.6A: A high steps-per-second number is a speedometer with no destination. What decides whether a run was worth it is dollars per checkpoint that reaches the held-out success target, counted across every billable phase including evaluation, logging, and failed runs.

This section assumes familiarity with Proximal Policy Optimization (PPO) rollout semantics from section 15.5 and advantage computation from section 15.3, because those steps contribute the learner-time term in the cost ledger. The simulator options discussed in section 17.3 and the JIT compilation behaviour covered in section 17.4 determine the rollout-time term. The cost-per-success discipline developed here reappears in Part VI alongside deployment budget constraints, where the same accounting applies to inference rather than training.

Big Picture

A robot manipulation policy trained overnight on eight GPUs looks impressive until the invoice arrives: four hours of that run were spent waiting for evaluation, another two on logging, and the checkpoint that actually solved the task appeared with forty minutes of budget left. Steps per second is a marketing number. For embodied AI, where training costs compound across hundreds of experiments, the metric that changes decisions is dollars per successful checkpoint. You will build a cost ledger that breaks every run into its true components, so you can stop optimizing the wrong bottleneck and start shipping policies that are both capable and affordable.

Two engineers stand at a whiteboard: one quotes 2,000,000 environment steps per second, the other quotes 400,000, and the slower system is the one that shipped a deployable policy under budget. That inversion is the whole problem of this section, and it only makes sense once GPU RL is treated as a cost-accounting exercise where simulator fidelity, PPO rollout semantics, reward terms, and reset distribution (the rule that decides where and how each parallel environment respawns after an episode ends) are versioned in the same training artifact.

This section develops the cost contract for massively parallel RL, where thousands of simulated environments run in lockstep on a single GPU to generate rollouts (the trajectories of states, actions, and rewards a policy produces while acting in the environment). We define the denominator for every claim: environment steps per second, policy updates per minute, wall-clock to target success, GPU memory at peak, evaluation time, and dollars per successful checkpoint.

The key question is practical: did the optimization make learning cheaper, or did it only move time from rollout collection into compilation, synchronization, logging, or evaluation? A run reporting 2,000,000 steps per second can still cost more than a run reporting 400,000 steps per second: if the faster system spends 40 percent of wall-clock on evaluation and another 15 percent on logging, the slower system reaches the 90 percent held-out threshold first (held-out meaning measured on evaluation seeds withheld from training, not merely re-run on the same conditions used to update the policy) and at lower dollar cost. A throughput number without a success threshold is a speedometer reading on a road with no destination. Figure 17.6A frames the tension this section resolves: raw speed on its own says nothing about whether a deployable policy was reached within budget. Figure 17.6B makes the accounting concrete, tracing how each wall-clock phase feeds the single cost ledger introduced below.

W_roll Rollout env steps W_learn Learner optimizer W_eval Evaluation held-out W_sync Sync + Log overhead Cost Ledger W = W_roll + W_learn + W_eval + W_sync + W_log $ per successful checkpoint = (W / 3600) x price / success_rate
Figure 17.6B: The four wall-clock phases of a GPU RL run (rollout, learner, evaluation, sync and log) all feed into a single cost ledger. The ledger sums billable time across all phases and converts it to dollars per successful checkpoint, the metric that drives hardware and algorithm decisions.
Report The Target, Not Only The Rate

Steps per second is a systems metric. Wall-clock to held-out success is the learning metric that matters to a builder deciding what to run next.

A common assumption is that maximizing environment steps per second minimizes training cost and time to a deployable policy. That assumption typically fails in embodied AI, because the phases it ignores are often the largest share of wall-clock: Evaluation overhead, compilation, synchronization stalls, logging, and failed runs all consume billable time without producing useful gradient signal. A system running at 2,000,000 steps per second can cost more than a system at 400,000 steps per second when the faster system spends the majority of its wall-clock outside the rollout phase. Treat throughput as one term in a cost ledger. The metric that drives hardware and algorithm decisions is dollars per first checkpoint that reaches the held-out success target, counted over all billable phases and all failed runs.

Theory

Let a run collect \(S\) environment steps in \(W\) wall-clock seconds. The raw throughput is \(S/W\), but the cost metric should include training, evaluation, checkpointing, and failed runs. If the target is a 90 percent held-out success rate, the relevant question is how many dollars and minutes were spent before the first checkpoint reached that target.

In contact-rich manipulation and legged locomotion, the throughput-versus-sample-efficiency tradeoff has a physical edge that pure RL benchmarks hide. Isaac Lab locomotion runs with 4,096 parallel Anymal environments and a PPO rollout horizon of 24 steps typically saturate (in practice, on this class of hardware; exact numbers vary with driver version and environment complexity) an A100 at around 200,000 environment steps per second (as of 2024, on Isaac Lab with RSL-RL). Doubling the batch to 8,192 raises device utilization but stretches policy lag (the real-time delay between when the environment state was sampled and when the resulting action, computed from that stale state, actually reaches the robot) to roughly 48 real-time milliseconds per update cycle. For a quadruped recovering from a push disturbance, that lag can decide between a recoverable stumble and a fall, because the contact phase that needs the corrective torque command typically lasts only 60 to 80 ms for this class of push-recovery task. Smaller batches keep the policy fresher but leave the GPU at 40 to 50 percent utilization, which wastes the hardware budget. The RSL-RL locomotion stack fixes this by tuning rollout horizon rather than batch size: fix the environment count at what fills GPU memory, then shorten the horizon until the update rate matches the task's fastest transient dynamics. The horizon matters more than raw step count. Halving it from 24 to 12 steps on 4,096 environments cuts the policy lag from 48 ms to 24 ms while collecting the same 98,304 transitions per update, because the robot receives a fresher policy twice as often within the same wall-clock window.

Checkpoint

So far: the cost ledger accounts for rollout, learner, evaluation, and sync/log time; throughput and policy lag trade off against each other through batch size and rollout horizon; and the accounting loop below turns those measurements into a single per-checkpoint record.

Mechanism

The mechanism is an accounting loop: measure rollout time, learner time, evaluation time, synchronization time, peak memory, and target success in the same run. Only then can you decide whether the bottleneck is simulation, policy inference, advantage computation (the discounted, generalized-advantage-estimate term used to weight each action in the policy gradient), optimizer updates, logging, or evaluation.

Algorithm: GPU RL Cost-Ledger Accounting Loop

Input: policy \(\pi_\theta\), learning rate \(\alpha\), batch size \(B\), target success rate \(\tau\), held-out seed panel \(\mathcal{E}\), instance price \(c\) (USD/hr), maximum budget \(C_{\max}\)

Output: cost ledger row \((W_{\text{train}}, W_{\text{eval}}, M_{\text{peak}}, \hat{\rho}, C_{\text{total}})\) for the first checkpoint reaching \(\hat{\rho} \ge \tau\)

  1. Record instance type, \(c\), \(B\), \(\tau\), and \(\mathcal{E}\) in the ledger header before launch.
  2. Start the rollout timer after the first compiled step; measure rollout wall-clock \(W_{\text{roll}}\) per update using torch.cuda.synchronize() at each phase boundary.
  3. Collect \(B\) transitions from \(N\) parallel environments; record peak GPU memory \(M_{\text{peak}}\) in GB.
  4. Compute advantages \(\hat{A}_t = \sum_{k=0}^{T} (\gamma \lambda)^k \delta_{t+k}\) and update \(\theta \leftarrow \theta - \alpha \nabla_\theta \mathcal{L}(\pi_\theta)\); measure learner wall-clock \(W_{\text{learn}}\).
  5. At each evaluation checkpoint, run \(\pi_\theta\) on \(\mathcal{E}\) and compute held-out success rate \(\hat{\rho}\); record evaluation wall-clock \(W_{\text{eval}}\).
  6. Accumulate total wall-clock \(W = W_{\text{roll}} + W_{\text{learn}} + W_{\text{eval}} + W_{\text{sync}} + W_{\text{log}}\) and billable cost \(C = (W / 3600) \cdot c\).
  7. If \(\hat{\rho} \ge \tau\), write the ledger row and stop; report \((C, W, M_{\text{peak}}, \hat{\rho})\) as the cost-to-success result.
  8. If \(C \ge C_{\max}\) before \(\hat{\rho} \ge \tau\), label the run as failed, record it in the ledger, and include it in the aggregate cost estimate.
  9. Identify the dominant bottleneck: compare \(W_{\text{roll}}, W_{\text{learn}}, W_{\text{eval}}, W_{\text{sync}}, W_{\text{log}}\) as fractions of \(W\).
  10. Report throughput as \(S / W_{\text{roll}}\) (steps per rollout second) and learning cost as \(C / \hat{\rho}\) (dollars per unit success); never mix denominators across ledger rows.

Step-Through: Cost-Ledger Accounting Loop

Trace the cost ledger with two competing runs to the same 90 percent held-out target, plugging real numbers into \(W = W_{\text{roll}} + W_{\text{learn}} + W_{\text{eval}} + W_{\text{sync}} + W_{\text{log}}\) and \(C = (W / 3600) \cdot c\).

Run A (fast simulator, \(c = 3.20\)/hr). Reaches target with \(W_{\text{roll}} = 600\) s, \(W_{\text{learn}} = 240\) s, \(W_{\text{eval}} = 900\) s, \(W_{\text{sync}} = 180\) s, \(W_{\text{log}} = 120\) s. Steps collected: \(1.4 \times 10^9\).

  1. Throughput: \(S / W_{\text{roll}} = 1.4 \times 10^9 / 600 = 2{,}333{,}333\) steps per rollout second. Impressive headline.
  2. Total wall-clock: \(W = 600 + 240 + 900 + 180 + 120 = 2{,}040\) s.
  3. Rollout fraction: \(600 / 2{,}040 = 29\%\). Evaluation fraction: \(900 / 2{,}040 = 44\%\). The run is evaluation-bound, not simulation-bound.
  4. Cost: \(C = (2{,}040 / 3600) \times 3.20 = \$1.81\).

Run B (slower simulator, \(c = 2.20\)/hr). Reaches the same target with \(W_{\text{roll}} = 1{,}100\) s, \(W_{\text{learn}} = 220\) s, \(W_{\text{eval}} = 300\) s, \(W_{\text{sync}} = 60\) s, \(W_{\text{log}} = 40\) s. Steps collected: \(5.0 \times 10^8\).

  1. Throughput: \(5.0 \times 10^8 / 1{,}100 = 454{,}545\) steps per rollout second. Five times slower on the speedometer.
  2. Total wall-clock: \(W = 1{,}100 + 220 + 300 + 60 + 40 = 1{,}720\) s.
  3. Cost: \(C = (1{,}720 / 3600) \times 2.20 = \$1.05\).

Verdict. Run B is 42 percent cheaper (\(\$1.05\) versus \(\$1.81\)) and reaches the target in less total wall-clock (\(1{,}720\) s versus \(2{,}040\) s), despite quoting one-fifth the steps per second. The step-rate headline pointed at the wrong winner; the ledger pointed at the right one.

When timing CUDA-based simulators such as Isaac Lab or Isaac Gym, call torch.cuda.synchronize() immediately before reading time.perf_counter() in essentially every case where phase-level attribution matters. CUDA kernel launches are asynchronous, so a timer that wraps the rollout call without a sync barrier measures kernel-launch latency rather than actual GPU compute time, silently reporting rollout as two to five times faster than it is. The resulting bottleneck diagnosis is wrong: the run looks learner-bound when it is actually simulation-bound, and you tune the wrong component. One sync call per phase boundary costs negligible overhead and makes the timing trustworthy. The JIT-compilation pitfall discussed later in this section under Common Pitfall interacts with this same sync discipline: compilation time must be logged separately from steady-state rollout time, or the two errors compound.

Worked Example

Code Fragment 17.6.1 computes the metrics that should appear together in a cost report. The same artifact contains throughput, wall-clock to target, evaluation overhead, and compute spend.

# Compute throughput and cost from one RL training run.
# The target-success checkpoint, not peak steps per second, drives the decision.
env_steps = 1_200_000_000
train_minutes = 42.0
eval_minutes = 6.0
gpu_dollars_per_hour = 2.20
heldout_success = 0.92
target_success = 0.90

total_minutes = train_minutes + eval_minutes
steps_per_second = env_steps / (train_minutes * 60)
total_cost = (total_minutes / 60) * gpu_dollars_per_hour
cost_per_billion_steps = total_cost / (env_steps / 1_000_000_000)

print(f"train throughput: {steps_per_second:,.0f} env steps/s")
print(f"total wall-clock: {total_minutes:.1f} min")
print(f"held-out success: {heldout_success:.2f}")
print(f"target reached: {heldout_success >= target_success}")
print(f"total compute cost: ${total_cost:.2f}")
print(f"cost per billion steps: ${cost_per_billion_steps:.2f}")
train throughput: 476,190 env steps/s total wall-clock: 48.0 min held-out success: 0.92 target reached: True total compute cost: $1.76 cost per billion steps: $1.47
Code Fragment 17.6.1 computes a cost report from one training run. The target-success line keeps throughput honest by tying the speed claim to held-out behavior, while evaluation minutes keep wall-clock accounting complete.

Expected output: the trace should include both systems and learning metrics. A run that reports 476,190 steps per second but omits held-out success has not shown that those steps bought a deployable policy.

Library Shortcut

In practical systems, rely on the framework's profiler, GPU telemetry, and logger rather than hand timing one function. Isaac Lab, RSL-RL, rl_games, SKRL, Brax, and MJX can all produce impressive throughput; the engineering shortcut is to export comparable cost records from the same evaluation script.

Practical Recipe

  1. Define the success target before training, such as 90 percent held-out success across 256 evaluation seeds.
  2. Measure rollout, learning, evaluation, logging, and checkpoint time separately.
  3. Track peak GPU memory, utilization, host-device transfer time, and compilation time where relevant.
  4. Report dollars per target-reaching checkpoint, not only dollars per hour.
  5. Repeat the run across seed panels when the result will support a paper table or hardware decision.
Common Failure Mode

The common mistake is to maximize training throughput by reducing evaluation frequency, then miss the first checkpoint that actually generalizes. Evaluation is part of the wall-clock budget, not an optional afterthought.

Common Pitfall

JAX-based simulators such as Brax and MJX incur a significant Just-In-Time (JIT) compilation cost on the first call, which can take 30 to 90 seconds depending on environment complexity. If you measure steps per second starting from launch rather than from the first post-compilation step, the reported throughput is artificially low and the comparison against an eager-mode simulator like Isaac Gym is invalid. Log compilation time separately and start the throughput clock only after the first compiled rollout completes. A related trap: comparing cost numbers from two runs that used different held-out seed panels makes the success rates incommensurable even when the step counts are identical.

Practical Example

A team choosing between two GPU instances should compare them on one script that trains to the same held-out success target. The faster instance can still be the worse choice if it runs out of memory, needs a smaller batch, or spends more time compiling and evaluating.

Real-World Application: Quadruped Locomotion at ETH Zurich and NVIDIA

The "Learning to Walk in Minutes" pipeline behind ANYmal and the Isaac Lab locomotion stack reports its headline as wall-clock to a walking gait on a single GPU, not peak steps per second, precisely because the buying decision is which GPU reaches a deployable controller fastest. NVIDIA's Isaac Lab benchmarks pair throughput with time-to-target on identical held-out terrain so quadruped teams can compare an A100 against an L40S on cost-per-controller rather than on a raw speedometer number.

Lab: Profile Where Your RL Budget Actually Goes

Goal: empirically discover that a higher step rate does not always mean a cheaper run by building a per-phase cost ledger for a real PPO training loop.

Tools needed: Python with stable-baselines3, gymnasium, and time.perf_counter(); a CPU or single GPU is enough. Train PPO on CartPole-v1 or LunarLander-v2 for about 100k timesteps.

What to do: instrument the loop to record rollout time, learner (gradient) time, and a periodic evaluation phase (run the greedy policy on 20 held-out seeds) separately. Set a success target (for example, mean return above 195 on CartPole) and stop the clock at the first checkpoint that reaches it. Compute total wall-clock, the fraction in each phase, and a synthetic cost using any dollars-per-hour rate.

What to vary: sweep evaluation frequency (every 2k, 10k, 50k steps) and rollout horizon (n_steps of 256, 1024, 4096).

What to observe: which configuration reaches the target with the lowest cost. You should see evaluation frequency dominating wall-clock at the aggressive setting while still using the same simulator, reproducing the headline lesson that the fastest-stepping run is rarely the cheapest successful one.

Memory Hook

The fastest run is not always the cheapest run. The cheapest successful run is the one that reaches the target before curiosity turns into a hyperparameter sweep.

Research Frontier

Heterogeneous and disaggregated GPU RL stacks (2024-2025). Recent work separates the rollout worker pool from the learner on different GPU tiers to cut cost per sample. RL^3 (Liang et al., 2024, arXiv:2406.11001) shows that routing rollout to cheaper A10 nodes while keeping the optimizer on an A100 reduces dollars-per-checkpoint by 40 percent on locomotion benchmarks without touching sample efficiency.

Compile-time-aware training schedules (2024-2025). NVIDIA's Isaac Lab 2.0 release and the accompanying FlexRL paper (2025) expose per-phase compilation profiles so schedulers can allocate evaluation budget only after the JIT warmup cost is amortized. This shifts the bottleneck diagnosis problem from manual instrumentation to automated phase accounting.

Learned cost models for hyperparameter search (2024-2026). Groups at CMU and ETH Zurich (Eschmann et al., 2024, RSS) are training surrogate models that predict dollars-to-success for a given batch size, rollout horizon, and instance type before launching the full run, turning the cost ledger into an input to Bayesian optimization rather than a post-hoc report.

Open problem for PhD students. No agreed benchmark exists for cost-to-success across simulators: Isaac Lab, MJX, and Brax report throughput on different tasks, with different evaluation cadences and held-out panels, making cross-system cost comparisons invalid. A student could define a suite of three to five contact-rich manipulation tasks with a shared evaluation protocol and held-out panel, run all three simulators to the same success threshold on identical hardware, and publish the first construct-matched cost-per-success comparison. The methodological contribution, a reusable ledger schema and evaluation harness, would be as durable as the numbers.

Self Check

Can you report steps per second, wall-clock to target, evaluation overhead, peak memory, instance cost, failed-run count, and held-out success from one artifact? If not, the cost claim is incomplete.

The Same-Denominator Rule

Every number needs a denominator, a principle called the same-denominator rule. Steps per second uses training seconds. Wall-clock to target uses training plus evaluation seconds. Cost uses all billable time. Paper tables and engineering decisions should not mix these denominators. Concretely: reporting Run A's steps per second (measured over rollout seconds only) next to Run B's dollars per success (measured over rollout, learner, evaluation, sync, and log seconds combined) in the same table row implies a direct comparison that the two numbers cannot support, because they were integrated over different windows of the same run.

Think of two runners competing in a race where one is timed only on the track and the other is timed from the parking lot. The track split looks faster, but it hides the walk to the start line. The same-denominator rule says both runners must be measured from the same starting gun to the same finish line: if your cost clock starts at rollout but your competitor's starts at launch (including compilation), you are not comparing the same race, and the faster-looking number may belong to the slower system.

In embodied AI this matters because teams decide robot hardware purchases and deployment budgets by comparing training runs. A locomotion controller that appears twice as cheap may reflect only training seconds while its competitor counted evaluation too. It may also exclude three failed runs that consumed half the real budget. A team that buys cheaper GPUs from a mismatched comparison discovers the error only after the hardware arrives.

The rule requires a single accounting window: one script, one run, one artifact. Every phase timer starts and stops inside that window, so all fractions sum to total billable time. Two runs compare only when both ledgers share the held-out seed panel and the success definition, which surfaces denominator drift at merge time instead of at paper review.

Report the bottleneck breakdown. A low throughput run may be simulation-bound, learner-bound, memory-bound, evaluation-bound, logging-bound, or compilation-bound. Each bottleneck implies a different fix.

Practical Tool Choices For This Section
Tool or LibraryRole in the TopicBuilder Advice
Steps per secondRaw simulator and learner throughputUse it to locate systems bottlenecks, not to claim policy quality.
Wall-clock to targetMinutes until held-out success threshold is reachedUse it as the primary training-speed metric.
Peak GPU memoryCapacity pressure from rollout, model, and optimizer stateUse it to explain batch-size limits and instance choice.
Evaluation overheadTime spent measuring held-out behaviorUse it in total wall-clock because evaluation frequency changes checkpoint selection.
Cost per successBillable compute until the first target-reaching checkpointUse it when comparing GPU instances, frameworks, or recipes.

Each tool in that table contributes a column to one shared record, and the structure that binds those columns together is the cost ledger itself. A robust implementation starts with a cost ledger. The ledger makes it impossible to claim a throughput win from one run and a success win from another run.

  1. Start the ledger before launch with instance type, price, batch size, target metric, and evaluation cadence.
  2. Update the ledger at each checkpoint with train seconds, eval seconds, peak memory, success, and reset reasons.
  3. Mark failed runs explicitly so cost estimates include search and debugging, not only the winning run.
  4. Save profiler summaries with the same run ID as the policy checkpoint.
  5. Compare cost only when success is computed on the same held-out panel.
# Record one cost ledger row for a GPU RL checkpoint.
# Keep systems metrics and held-out behavior in the same artifact.
from dataclasses import dataclass, asdict

@dataclass
class CostLedgerRow:
    checkpoint: int
    train_minutes: float
    eval_minutes: float
    peak_gpu_gb: float
    heldout_success: float
    billable_cost_usd: float

    def as_row(self) -> dict[str, object]:
        return asdict(self)

row = CostLedgerRow(
    checkpoint=320,
    train_minutes=42.0,
    eval_minutes=6.0,
    peak_gpu_gb=18.4,
    heldout_success=0.92,
    billable_cost_usd=1.76,
)
print(row.as_row())
{'checkpoint': 320, 'train_minutes': 42.0, 'eval_minutes': 6.0, 'peak_gpu_gb': 18.4, 'heldout_success': 0.92, 'billable_cost_usd': 1.76}
Code Fragment 17.6.2 records one checkpoint-level cost ledger row. Keeping peak memory, evaluation time, held-out success, and billable cost together prevents later tables from comparing numbers that came from different runs.

Once such a row is recorded, its real value shows up the moment the cost it reports comes back higher than expected. When a cost result disappoints, avoid changing the algorithm first. Identify whether the budget was lost to simulator stepping, learner updates, GPU memory pressure, host-device transfers, compilation, evaluation, logging, or failed hyperparameter searches. Each cause has a different repair.

Evaluation Recipe

For throughput and cost claims, compare only construct-matched metrics that are co-computed in one pass on one configuration: same environment panel, same policy checkpoint, same held-out seed set, same perturbation suite, same success definition, and same cost accounting window. Save throughput, wall-clock, memory, evaluation overhead, success, failure labels, and billable cost as one artifact.

Key Takeaway

Throughput is useful when it lowers wall-clock and cost to a held-out behavior target. Raw steps per second is only the first line of the ledger.

Exercise 17.6.1

Build a cost ledger for two GPU RL recipes. For each, record steps per second, train minutes, evaluation minutes, peak memory, instance price, held-out success, failed-run count, and dollars to first target-reaching checkpoint.

Project Ideas

Beginner (weekend): Cost ledger for a Gymnasium cartpole run. Instrument a PPO training loop on CartPole-v1 using Gymnasium to record rollout time, learner time, evaluation time, and total compute cost per run; the key challenge is correctly placing time.perf_counter() barriers so each phase is measured separately and the fractions sum to total wall-clock without double-counting. Intermediate (1-2 weeks): Batch-size vs. rollout-horizon sweep in Isaac Lab. Train an AnymalC locomotion policy in Isaac Lab using RSL-RL, sweeping over environment counts (1024, 2048, 4096) and PPO rollout horizons (8, 16, 24, 48 steps), and log a cost ledger row for each configuration that records steps per second, wall-clock to 80 percent held-out success, peak GPU memory, and dollars to first target checkpoint; the key challenge is ensuring every ledger row uses the same 256-seed held-out panel and calls torch.cuda.synchronize() at every phase boundary so the bottleneck attribution (simulation-bound vs. learner-bound vs. evaluation-bound) is trustworthy across configurations.

What's Next?

This section turned throughput into a cost ledger: steps per second, wall-clock to target, evaluation overhead, peak memory, failure count, and dollars per successful checkpoint. Return to Chapter 17 with one rule for every GPU RL result: speed and success belong in the same artifact.

References & Further Reading
Foundational Papers, Tools, and Practice References

Rudin, N. et al. (2022). Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning. CoRL.

Rudin et al. are a benchmark for fast wall-clock locomotion. For cost engineering, read the result as a prompt to ask what hardware, evaluation cadence, and success threshold define the headline time.

Paper

Makoviychuk, V. et al. (2021). Isaac Gym: High Performance GPU-Based Physics Simulation For Robot Learning. arXiv.

Isaac Gym is the right source for understanding raw GPU simulation throughput. In this section, use it to separate impressive step rates from full cost accounting that includes evaluation and failed runs.

Paper

Freeman, C. D. et al. (2021). Brax: A Differentiable Physics Engine for Large Scale Rigid Body Simulation. arXiv.

Brax is relevant because JAX-native simulation can shift the bottleneck from stepping to compilation, memory, or evaluation. Cost reports should account for those phases separately.

Paper

NVIDIA Isaac Lab documentation.

Isaac Lab provides a realistic setting for end-to-end cost measurement: task setup, training runner, checkpointing, play scripts, and evaluation videos. Those components all consume wall-clock time.

Tool

Google DeepMind MuJoCo MJX documentation.

MJX is useful when comparing accelerator-native MuJoCo-style workloads. Its static-shape and compilation behavior should be logged separately from steady-state steps per second.

Tool

RSL-RL repository.

RSL-RL gives readers concrete PPO runner code to profile. It is useful for locating whether time is spent in rollout storage, advantage computation, optimizer updates, logging, or evaluation.

Tool