7 routes42 sections324 units

Unit 8.2 · about 4 h

222 / 324

Streams, asynchronous copies and honest timing

Every speedup claim in this section stands or falls on timing discipline. Async execution makes naive timers lie, and a hidden sync can pose as a slow kernel.

  • explain
  • measure

You can now

  • Explain why GPU launches return before the work finishes and where PyTorch syncs for you.
  • Order wait_stream and record_stream correctly when a side stream consumes a default-stream tensor.
  • Time a GPU operation with events and show why a bare wall clock understates it.

Covers

  • Device streams, asynchronous copies and synchronization
  • Accidental synchronization and measurement error

Study, in this order

3 steps

  1. Asynchronous execution and CUDA streams
    PyTorch - checkpointing, numerical accuracy and CUDA semantics

    Asynchronous execution: enqueue semantics, CUDA_LAUNCH_BLOCKING, and the Event timing example; CUDA streams: default-stream auto-sync, the wait_stream plus record_stream fix, and Stream semantics of backward passes

    Depth · Skip the TF32, GEMM precision, allocator-tuning and CUDA-graph sections here. They belong to later units.

  2. Pinned memory and asynchronous copies
    PyTorch - checkpointing, numerical accuracy and CUDA semantics

    Best practices, Use pinned memory buffers: pin_memory, non_blocking copies, and overlapping transfer with compute

  3. Operations that force synchronization
    PyTorch - reliability and performance recipes

    GPU specific optimizations, Avoid unnecessary CPU-GPU synchronization: the print, item, copy, nonzero and data-dependent-control-flow list

Focus on

  • Launches enqueue; they do not execute. On-device order is preserved per stream, and PyTorch syncs around CPU-GPU copies on the default stream only.
  • Side streams get no automatic safety. The consumer stream waits on the producer with wait_stream, and the tensor records its new stream with record_stream so its memory is not reused early.
  • non_blocking=True is a request, not a command. From pageable host memory the copy still syncs; pin the source first.
  • Backward follows forward stream placement. Grads produced under a side-stream backward must be consumed in the same stream context or after an explicit wait.

Reproduce closed-book

On a CUDA GPU, warm up, then time a \(2048 \times 2048\) fp32 matmul both ways: CUDA events around the op with a synchronize before reading, versus a bare perf_counter around the launch. The matmul is \(2 \times 2048^3\), about 17.2 GFLOP, so the event time is a few milliseconds at most (4.1 ms on an RTX 3050 6 GB), while the bare clock reads microseconds (0.007 ms there) because it measures enqueue only. Exact numbers depend on hardware; the size of the gap is the assertion.

Traps

  • Timing with time.perf_counter and no sync, then reporting the result as kernel time. You timed the launch, not the work.
  • Calling .item(), printing a CUDA tensor, or branching on one inside the timed region. Each forces a sync and the stall gets billed to the wrong line.
  • Assuming default-stream safety extends to side streams. In the docs example, sum on a side stream may start before normal_ finishes on the default stream. The side stream must wait_stream on the default stream, and record_stream protects the tensor if it is freed while the side stream still uses it.

Practice

The section mini-project covers this: synchronized phase timing with explicit stream boundaries.

Self-test

  1. An Event-timed matmul reports 4.1 ms while a bare wall clock reports 0.007 ms. Which is the kernel time and why?

  2. Data comes from pageable host memory with .to(device, non_blocking=True). Is the copy asynchronous?

  3. loss.backward() runs under torch.cuda.stream(s). Where may the .grad tensors be consumed?

  4. Which of print(t), t.item() and t.to('cpu') force a host sync for a CUDA tensor t?

Completion criterion

Stop when

Your two-way timing shows the enqueue gap on your GPU, and you can point at the sync in any snippet that prints, copies, or branches on a CUDA tensor.

Mark passed, then open 8.3 Only mark this when you can do it without notes.

Leads to

Resources for this unit

  • PyTorch - reliability and performance recipes
    PyTorchprimarycourse
    Use the Profiler, Automatic Mixed Precision, model loading and Benchmark recipes, then the Performance Tuning Guide. Apply each to one compact model from an earlier section and keep a CPU fallback when CUDA is unavailable.
  • PyTorch - checkpointing, numerical accuracy and CUDA semantics
    PyTorchrequiredreference
    Use the official user-guide entries for torch.utils.checkpoint, numerical accuracy, CUDA semantics, reproducibility and serialization. Predict memory categories before measuring and define resume equivalence before running.

Also in this section

  • PyTorch - compiler troubleshooting
    PyTorchrequiredreference
    Read graph breaks, guards, recompilations and logging. Compile one stable fragment, intentionally trigger a graph break or recompilation, inspect it, and compare eager and compiled outputs and gradients.
  • Deep Learning Training Debugger
    Roadmap-Finalreferenceassessment
    Use the failure-injection, measurement and evidence rules as the deeper standard. The full Tier 2 project is a later route and is not added to this stage milestone.
  • TensorTonic - mixed-precision memory and transformer FLOPs
    TensorTonicsupportpractice
    Solve only Mixed-Precision Training Memory Accountant and Transformer Training FLOP Estimator. Reconcile both with the compact model's profiler and document every included and excluded term.
  • Learn PyTorch - profiler walkthrough
    Daniel Bourkeoptionalimplementation
    Use notebook 10 only if the official profiler route remains unclear. Transfer the relevant annotations into the compact model instead of keeping the tutorial code.
  • TrenTorch - precision, checkpointing and resume
    TrenTorchsupportpractice
    Solve Loss Scaling, FP16/BF16 Representable Range, Gradient Checkpointing and Resume-from-checkpoint in NumPy, then reproduce each behavior with the PyTorch API in the compact model.
  • Python os - `os.replace`
    Python Software Foundationreferencereference
    Read os.replace for the atomic-rename step of checkpoint writes: save to a temp file in the same directory, flush and fsync, then replace the final name.
  • Hands-On Machine Learning with Scikit-Learn and PyTorch
    Aurelien Geron (O'Reilly, 2025)supporttheory
    Read Appendix B, Reduced Precision Models and Mixed-Precision Training, for why float16 training underflows and what fp32 primary weights and loss scaling fix.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels