diff --git a/crates/ml/src/trainers/dqn/trainer/training_loop.rs b/crates/ml/src/trainers/dqn/trainer/training_loop.rs index 16a65aaa2..e38189078 100644 --- a/crates/ml/src/trainers/dqn/trainer/training_loop.rs +++ b/crates/ml/src/trainers/dqn/trainer/training_loop.rs @@ -1473,10 +1473,10 @@ impl DQNTrainer { } } + // Acquire write lock ONCE for the entire training loop — not per-step. + // Per-step lock acquisition was burning 696s/epoch due to async yield overhead. + let mut agent = self.agent.write().await; for _step in 0..num_training_steps { - // Single write lock for both sample + fused step — eliminates - // read→write lock cycling overhead (~43ms per step from contention). - let mut agent = self.agent.write().await; let sample_start = std::time::Instant::now(); {