BACK TO LESSONPARALLEL HORIZONSREAD // 02

LESSON READING // 02

TASK CONCURRENCY

HISTORICAL ANCHORCUDA STREAMS → KEPLER HYPER-QREAD TIME · ABOUT 60 MIN

Use multiple streams to express independence between chunks, giving copies, kernels, and returns a chance to overlap while preserving each chunk's order.

Write down answers as you go; the estimate includes code tracing and practice.

PLAY THE INTERACTIVE LESSON
COURSE PACINGABOUT 60 MINUTES
  1. 01ORIENT + OBJECTIVES05 MIN
  2. 02MENTAL MODEL08 MIN
  3. 03DEEP DIVES15 MIN
  4. 04CODE TRACE12 MIN
  5. 05HISTORY + ECOSYSTEM08 MIN
  6. 06PRACTICE + REVIEW12 MIN
ACCELERATED COMPUTING CAPABILITY MAPINDEPENDENT LEARNING COMPANION · NOT AN NVIDIA COURSE OR CERTIFICATION
PATH // 02
FOUNDATIONALPROFILINGNSIGHT SYSTEMS
THE OFFICIAL PATH EMPHASIZES

Treat the GPU program as a workflow and use timelines to find gaps among CPU submission, movement, and computation.

HOW THIS LESSON CONNECTS

The game teaches stream dependencies; the lab turns them into a real trace that separates an asynchronous API from actual overlap.

SUGGESTED PREREQUISITES
  • Lessons 00–01
  • H2D / D2H basics
  • In-stream ordering
PRACTICE TOOLS
  • Nsight Systems
  • CUDA Streams / Events
  • Pinned Host Memory
01 · 05 MIN

ORIENT + OBJECTIVES

REMEMBER THIS FIRST

Concurrency comes from independent work and correct dependencies; an asynchronous API only communicates that possibility.

BY THE END, YOU SHOULD BE ABLE TO

  1. 01

    Draw dependency timelines for one stream and several streams.

  2. 02

    Identify operations that may overlap and those needing stream order or events.

  3. 03

    Explain how pinned host memory, copy engines, and default-stream semantics affect overlap.

  4. 04

    Move synchronization to actual result-consumption boundaries.

02 · 08 MIN

BUILD THE MENTAL MODEL

  1. 01
    QUEUE

    Commands in one stream execute in submission order, forming a natural dependency chain.

  2. 02
    SPLIT

    A stream per independent chunk lets H2D, kernel, and D2H work from different chunks interleave.

  3. 03
    JOIN

    Submit all independent work first, then synchronize only before results are actually consumed.

03 · 15 MIN

CONCEPT DEEP DIVES

01

A STREAM MEANS ORDER

It describes an ordered command flow. Different streams may execute concurrently; they are not promised to do so.

02

DEPENDENCIES FOLLOW DATA

Keeping each chunk's copy, kernel, and return in one stream preserves local ordering without serializing other chunks.

03

OVERLAP HAS PREREQUISITES

Real overlap can require device capability, pinned host memory, sufficient resources, and freedom from implicit synchronization.

PART 01

STREAMS DEFINE ORDER BEFORE THEY OFFER CONCURRENCY

Commands in one stream retain submission order, so H2D → kernel → D2H naturally describes one chunk. Placing three chunks in that same stream is correct but serializes independent chunks. A stream per chunk preserves each local chain while exposing concurrency across chains.

Different streams may execute concurrently; they are not guaranteed to. Resource pressure, implicit synchronization, default-stream behavior, or real dependencies can serialize them. Streams declare independence and the runtime realizes what current conditions permit.

PAUSE AND REASONWhy can one H2D stream, one kernel stream, and one D2H stream break correctness?

REFERENCE ANSWERA chunk's kernel may run before its H2D, or D2H before its kernel. Events would be needed to rebuild data dependencies.

PART 02

TRANSFER OVERLAP DEPENDS ON BOTH HOST AND DEVICE

The host behavior and DMA path of cudaMemcpyAsync depend on memory type and direction. Pinned host memory provides stable direct DMA access and is commonly required for H2D/D2H overlap. Pageable memory can trigger staging or synchronization.

The device also needs available copy engines, and kernel resource use must leave concurrency possible. Verify with a device timeline rather than an API name. Too many tiny chunks can lose to launch and scheduling overhead.

PAUSE AND REASONDoes a quickly returning API prove the copy overlapped a kernel?

REFERENCE ANSWERNo. It only shows the host did not wait for the full operation. A device timeline must show actual DMA/kernel overlap.

PART 03

EVENTS EXPRESS LOCAL DEPENDENCIES

cudaDeviceSynchronize waits broadly for prior device work. If stream B depends only on one operation in stream A, record an event in A and make B wait on that event. Unrelated streams and the host can keep moving.

CUDA Graphs can reduce repeated submission overhead for a stable dependency graph, but they do not invent independence. Design correct dependencies first, then choose events or graphs for precision and overhead.

PAUSE AND REASONWhy is an event better when B depends only on A's H2D?

REFERENCE ANSWERIt creates only the required edge, while a device-wide synchronization waits for unrelated work too.

04 · 12 MIN

PUT IT BACK INTO CODE

PROGRAM MODELOne stream per chunk, one wait after submission
01for (int s = 0; s < 3; ++s) {02  cudaMemcpyAsync(d[s], h[s], bytes, H2D, stream[s]);03  kernel<<<grid, block, 0, stream[s]>>>(d[s]);04  cudaMemcpyAsync(out[s], d[s], bytes, D2H, stream[s]);05}06cudaDeviceSynchronize(); // before consuming results

TRACE THE CODE

  1. 01
    LOOPONE ITERATION OWNS ONE CHUNK

    The same s selects host buffer, device buffer, and stream, preventing accidental storage sharing.

  2. 02
    H2DSUBMIT INPUT ASYNCHRONOUSLY

    The host buffer still needs a valid lifetime until transfer completion.

  3. 03
    KERNELSTREAM ORDER PRESERVES LOCAL DEPENDENCY

    The kernel follows its chunk's H2D without an intervening host wait.

  4. 04
    JOINWAIT BEFORE RESULTS ARE CONSUMED

    Submitting all chunks first preserves the widest copy/compute/return overlap window.

REF · 02

KNOWLEDGE ATLAS

OPTIONAL REFERENCE · REVISIT AS NEEDED · OUTSIDE THE CORE 60 MINUTES

CORE VOCABULARY

Stream
An ordered device command sequence; different streams expose possible independence but do not promise concurrency.
Event
A recorded stream completion point used for timing or a precise cross-stream dependency.
Pinned Memory
Host memory that is not paged out, enabling a direct DMA path and supporting asynchronous transfer.
Copy Engine
Hardware that performs movement; count and direction support constrain overlap with compute or another copy.
CUDA Graph
A reusable graph of operations and dependencies that reduces repeated CPU submission overhead.
EXAMPLE

WORKED EXAMPLE

  1. 01
    SERIAL BASELINE

    3 × (2 + 5 + 2) = 27 ms when every chunk waits for the previous one.

  2. 02
    FIND CADENCE

    The 5 ms kernel is the slowest stage, so steady-state cadence is one chunk per 5 ms.

  3. 03
    ADD FILL + DRAIN

    The first chunk needs 9 ms; two more cadences add 10 ms: 9 + 2 × 5 = 19 ms.

RESULT

Ideal pipelining saves 8 ms, about a 1.42× speedup; it does not make movement disappear.

WHY IT MATTERS

Verify overlap on a timeline, then optimize the 5 ms bottleneck. Stream count is not the objective.

DIAGNOSTIC PLAYBOOK

01SYMPTOM

Multiple streams still form one line

INSPECT FIRST
Default stream, host-memory type, synchronization, and device capability
EVIDENCE
An aligned Nsight Systems view of host API, copies, and kernels
02SYMPTOM

More streams make it slower

INSPECT FIRST
Tiny chunks, launch cost, contention, and bandwidth saturation
EVIDENCE
A stream-count sweep with CPU submission and GPU utilization
03SYMPTOM

A consumer sometimes reads stale data

INSPECT FIRST
Cross-stream producer edges, buffer lifetime, and host reuse
EVIDENCE
An event dependency graph and explicit buffer ownership

HARDWARE → ECOSYSTEM

  1. 01ASYNC KERNELS + STREAMS

    The host can continue after dispatch.

    Programs can expose host, copy, and GPU overlap.
  2. 02KEPLER HYPER-Q

    More hardware work connections reduced false serialization.

    Software-expressed concurrency reached hardware more often.
  3. 03EVENTS + CUDA GRAPHS

    Broad waits became precise, reusable dependency graphs.

    The focus moved from more queues to better dependencies and lower launch cost.
05 · 08 MIN

HARDWARE + ECOSYSTEM COORDINATE

2012 · KEPLER HYPER-Q

CUDA streams predate Kepler. Hyper-Q mattered because more hardware work connections reduced false serialization between independent streams, giving software-expressed concurrency a better route into hardware.

06 · 12 MIN

PRACTICE + REVIEW

Why avoid cudaDeviceSynchronize immediately after every cudaMemcpyAsync?

  1. A. It corrupts the copy
  2. B. It blocks the host and closes the overlap window too early
  3. C. It clears device memory
REVEAL ANSWER
B

The placement of synchronization defines the concurrency boundary. Waiting too early serializes otherwise independent commands.

02TIMELINE

Three chunks share the default stream and each runs H2D→kernel→D2H. How many ordered chains result?

HINT

All commands are submitted to one stream.

REFERENCE ANSWER

One chain of nine operations. Chunk independence is not exposed.

03DEBUG

The host calls cudaStreamSynchronize after every chunk submission. Why is it correct but slow?

HINT

When can the next chunk be submitted?

REFERENCE ANSWER

The host waits for a full chunk before submitting the next, closing cross-chunk overlap. Submit first, then wait at consumption.

04DEPENDENCY

A kernel in B consumes data produced in A. Avoid a device-wide wait.

HINT

Record a local completion signal.

REFERENCE ANSWER

Record an event in A after production and call cudaStreamWaitEvent in B before submitting the consumer.

05DIAGNOSE

Multiple streams and async copies show no overlap. Name three checks.

HINT

Host memory, device capability, synchronization.

REFERENCE ANSWER

Check pinned host buffers, copy-engine/concurrency support, and explicit or implicit/default-stream synchronization; also inspect tiny task sizes and resource saturation.

LAB · 35–45 MIN

OPTIONAL HANDS-ON LAB

OUTSIDE THE CORE 60 MINUTES · REQUIRES A SUITABLE CUDA / GPU ENVIRONMENT

LAB GOAL

BUILD A MEASURABLE COPY–COMPUTE PIPELINE

Transform nine default-stream tasks into a stream-per-chunk pipeline and verify overlap and dependencies.

PROCEDURE

  1. 01

    Capture a pageable-memory, default-stream baseline.

  2. 02

    Use pinned memory and three non-blocking streams with H2D→kernel→D2H per chunk.

  3. 03

    Move synchronization after submission and add one event dependency.

  4. 04

    Annotate host API, copy engines, and kernels in Nsight Systems.

EVIDENCE OF COMPLETION

Submit before/after timelines, synchronization reasoning, and end-to-end time with hardware/task-size limits.

STRETCH CHALLENGE

Capture the stable sequence as a CUDA Graph and compare CPU submission overhead.

REF

GO DEEPER