Search…

Why GPUs and CUDA? A beginner's starting point

In this series (35 parts)
  1. Why GPUs and CUDA? A beginner's starting point
  2. A simple guide to CPUs, GPUs, TPUs, NPUs, FPGAs, and ASICs
  3. GPUs: from pixels to parallel supercomputers
  4. Your first CUDA program: kernels, threads, and grids
  5. Python GPU programming: CuPy vs Numba vs PyCUDA
  6. Thread hierarchy in CUDA: threads, blocks, warps, and grids
  7. Inside a modern NVIDIA GPU: SMs, schedulers, CUDA cores, and tensor cores
  8. Warp divergence in CUDA: detection and optimization
  9. Floating-point performance on GPUs: precision, FLOPs, and numerical error
  10. CUDA memory hierarchy: where your data lives matters
  11. Memory coalescing: the most important optimization you will learn
  12. Shared memory and tiling: the key to fast matrix operations
  13. Debugging and profiling CUDA programs
  14. Device functions, host functions, and CUDA function qualifiers
  15. Building reusable CUDA libraries with CMake and Python bindings
  16. CUDA synchronization and atomics: __syncthreads, atomicAdd, and barriers
  17. Parallel prefix sum and reduction: the core parallel primitives
  18. Concurrent data structures on the GPU
  19. CUDA streams and asynchronous execution
  20. cudaEventSynchronize and CUDA events: accurate kernel timing
  21. Dynamic parallelism: kernels launching kernels
  22. Unified virtual memory: one pointer for CPU and GPU
  23. Multi GPU CUDA: NCCL, NVLink, and peer access
  24. Memory allocation patterns and multi-dimensional arrays in CUDA
  25. Texture and constant memory: specialized caches
  26. CUDA occupancy and register pressure: performance tuning guide
  27. Case study: matrix multiplication from naive to cuBLAS speed
  28. Case study: implementing a convolution layer in CUDA
  29. Case study: reduction and histogram at scale
  30. Heterogeneous computing: CPU and GPU working together
  31. Advanced memory patterns: pinned memory, zero-copy, and more
  32. Advanced stream patterns and concurrent kernel execution
  33. Performance case studies and optimization patterns
  34. CUDA Sobel edge detection: from naive kernel to profiled pipeline
  35. Where to go from here: CUDA ecosystem and next steps

Start with the problem

Imagine that you need to brighten one photograph.

The photograph contains millions of pixels, and the same small calculation must be applied to every pixel. A CPU can process those pixels, but it has only a small number of powerful cores. Most of the work must wait its turn.

A GPU takes a different approach. It has many smaller processing units that can work on many pixels at the same time. Instead of finishing one task as quickly as possible, it is designed to finish a large collection of similar tasks together.

This difference is the reason GPU programming exists.

CPU and GPU have different strengths

A CPU is the general-purpose processor that runs your operating system and most application code. Its cores are good at complex decisions, changing instructions, and tasks where each step depends on the previous one.

A GPU is a helper processor built for throughput: completing a large amount of similar work. It works best when a problem can be divided into thousands of small pieces that can run mostly independently.

Better fit for a CPUBetter fit for a GPU
Parsing a configuration fileProcessing millions of pixels
Handling a web requestMultiplying large matrices
Running branch-heavy business logicTraining a neural network
Working on a small amount of dataSimulating many particles

A GPU is not a faster CPU, and it does not replace one. Real programs use both: the CPU organizes the work, and the GPU handles the large parallel part.

What CUDA is

CUDA is NVIDIA’s platform for programming NVIDIA GPUs.

Without CUDA, developers would need to express general calculations through graphics APIs. CUDA lets you write a function called a kernel and run many copies of it on the GPU.

A typical CUDA program follows this simple pattern:

  1. The CPU prepares some data.
  2. The data is copied to GPU memory.
  3. The CPU asks the GPU to run a kernel.
  4. Many GPU threads process different pieces of the data.
  5. The result is copied back to the CPU.

You do not need to understand kernels, threads, or GPU memory yet. The next articles introduce them one at a time.

When a GPU helps

A problem is a promising GPU candidate when:

  • there is a lot of data;
  • the same calculation is repeated many times;
  • many pieces can be processed independently; and
  • the calculation takes enough work to justify moving data to the GPU.

Image processing is a good example because each output pixel can often be calculated independently. Matrix operations are another: the same multiply-and-add pattern is repeated across many values.

When a GPU does not help

GPU acceleration has a cost. Data usually has to move between CPU memory and GPU memory, and launching GPU work has overhead.

A GPU may be the wrong choice when:

  • the input is small;
  • each step depends on the result of the previous step;
  • the code makes many different decisions; or
  • moving the data takes longer than processing it on the CPU.

The goal of CUDA programming is not to move everything to the GPU. It is to recognize the part of a program that has enough parallel work to benefit.

Why this series uses CUDA

CUDA is a practical place to learn GPU programming because it provides:

  • a C/C++ programming model;
  • mature debugging and profiling tools;
  • optimized libraries for common calculations; and
  • extensive use in scientific computing, graphics, and machine learning.

CUDA runs on NVIDIA GPUs, so it is not a vendor-neutral platform. However, the ideas you will learn—parallel threads, memory movement, synchronization, and performance trade-offs—also apply to other GPU programming systems.

What you will learn

This series starts with the story of how GPUs became programmable, then moves to your first CUDA kernel. From there, you will learn how threads are organized, where data lives, how threads coordinate, and how to measure and improve performance.

You only need basic C or C++ familiarity. No GPU programming experience is required.

What comes next

If you want a quick overview of other hardware such as TPUs, NPUs, FPGAs, and ASICs, read the optional article A simple guide to CPUs, GPUs, TPUs, NPUs, FPGAs, and ASICs.

Otherwise, continue directly to GPUs: from pixels to parallel supercomputers, which explains how graphics hardware evolved into the programmable processor used by CUDA.

Start typing to search across all content
↑ ↓ navigate Enter open Esc close