Creating and Using Streams
Issuing independent work queues.
Creating and Using Streams is a free CUDA Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the CUDA Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Independent Work Queues
A non-default stream is your own work queue. Two streams run independently, so the GPU can make progress on both at once. 🧵
The Stream Handle
A stream lives in a cudaStream_t handle. You create it once, pass it to your calls, and destroy it when you are done.
cudaStream_t stream;Creating a Stream
Call cudaStreamCreate to make a fresh stream. It allocates the queue the driver uses to schedule that stream's work.
cudaStreamCreate(&stream);Launching a Kernel in a Stream
A kernel's launch config has a fourth argument: shared memory size, then the stream. Pass your stream to queue the kernel there.
kernel<<<grid, block, 0, stream>>>(d_data);Two Streams, Two Tasks
Put one job on streamA and another on streamB. With no dependency between them, the GPU is free to run both concurrently.
kA<<<g, b, 0, streamA>>>(a);
kB<<<g, b, 0, streamB>>>(d);Async by Nature
Stream calls are asynchronous: the host returns immediately and keeps going. The GPU works through the queue on its own time.
Waiting on One Stream
Use cudaStreamSynchronize to block the host until just that stream finishes, instead of waiting on the whole device.
cudaStreamSynchronize(stream);Checking Without Blocking
Want a peek? cudaStreamQuery returns cudaSuccess if the stream is done and cudaErrorNotReady if it is still busy, without stalling you.
cudaStreamQuery(stream);Cleaning Up
When a stream is no longer needed, release it with cudaStreamDestroy. Pending work still completes before the handle is freed.
cudaStreamDestroy(stream);Non-Blocking Streams
Create a stream with the cudaStreamNonBlocking flag so it does not implicitly synchronize with the legacy default stream.
cudaStreamCreateWithFlags(&s, cudaStreamNonBlocking);More Streams, More Overlap
Spreading independent chunks over several streams lets the scheduler keep the engines fed. Beyond a few, returns diminish as hardware fills up.
Quick Check
How do you queue a kernel into a specific stream?
Recap
You can now create streams, launch kernels in them, sync or query, and destroy them. Independent streams unlock real concurrency. ✨
Frequently asked questions
Is the “Creating and Using Streams” lesson free?
Yes — the full text of “Creating and Using Streams” is free to read here on the web, and the CUDA Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the CUDA Academy course, upgrade to CoddyKit PRO.
What will I learn in “Creating and Using Streams”?
Issuing independent work queues. You practise CUDA Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start CUDA Academy?
No prior experience is required. CUDA Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Creating and Using Streams” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this CUDA Academy lesson?
Yes. Every CUDA Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The Default Stream Trap
- Creating and Using Streams
- Events for Timing and Sync
- Overlapping Copy and Compute