From CUDA source to silicon: tracing a vector-add kernel down to the GPU
A trivial CUDA program that adds two million-element vectors hides an enormous amount of machinery: producing one correct answer involves tens of millions of CPU instructions, hundreds of ioctls, and a memory-mapped doorbell register. The post walks the full path from C source to executing warps. It starts with nvcc, which is really a driver coordinating several compilers — cicc lowers device code to PTX, and ptxas turns PTX into architecture-specific SASS. PTX is a virtual ISA with infinitely many typed registers and no knowledge of real hardware limits, which is why simple operations like forming a global address take several verbose instructions.
When ptxas targets a concrete architecture (here an RTX 4090, sm_89), that abstraction collapses: a dozen virtual registers map onto a handful of physical ones, separate multiply-widen-add sequences fuse into single IMAD.WIDE instructions, and generic-to-global pointer conversions vanish into the addressing modes. Kernel arguments and launch geometry land in constant memory bank 0 at fixed offsets, since every thread reads the identical pointers and the constant cache can broadcast them to all 32 lanes at once. The compiled SASS lives in a cubin, which is just an ELF file like any Linux binary.
The build bundles that cubin with a copy of the PTX into a ‘fatbin,’ which is in turn embedded in the host executable. The SASS runs natively, while the compressed PTX rides along as a forward-compatibility fallback the driver can JIT into fresh SASS on GPUs the precompiled code doesn’t cover. The piece is also a small argument for curiosity-driven reverse engineering: with modern tooling, almost nothing about how computers work is truly opaque.
Read the full article
Continue reading at Hacker News →This is an AI-generated summary. Read the original for the full story.