<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cuda on Sanketh's Blog</title><link>https://sankethbk.github.io/blog/tags/cuda/</link><description>Recent content in Cuda on Sanketh's Blog</description><generator>Hugo -- 0.166.0</generator><language>en-us</language><lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://sankethbk.github.io/blog/tags/cuda/index.xml" rel="self" type="application/rss+xml"/><item><title>CUDA Profiling and Performance Measurement</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-04-2-cuda-profiling/</link><pubDate>Fri, 04 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-04-2-cuda-profiling/</guid><description>&lt;h1 id="cuda-profiling-and-performance-measurement"&gt;CUDA Profiling and Performance Measurement&lt;/h1&gt;
&lt;p&gt;The notes up to this point covered what makes CUDA kernels fast in theory: coalescing, tiling, occupancy, and asynchronous execution. This note covers how to &lt;strong&gt;measure&lt;/strong&gt; whether a kernel is actually fast and how to find the bottleneck when it is not.&lt;/p&gt;
&lt;p&gt;Profiling is what separates guessing from optimization. Without it, you can apply every best practice and still be slower than a simpler implementation.&lt;/p&gt;</description></item><item><title>CUDA Unified Memory: One Pointer, Two Processors</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-04-1-cuda-unified-memory/</link><pubDate>Fri, 04 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-04-1-cuda-unified-memory/</guid><description>&lt;h1 id="cuda-unified-memory-one-pointer-two-processors"&gt;CUDA Unified Memory: One Pointer, Two Processors&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-09-02-2-cuda-streams"&gt;previous note&lt;/a&gt; covered explicit CUDA streams and how to overlap host-device transfers with computation. This note covers &lt;strong&gt;Unified Memory&lt;/strong&gt;, an alternative to explicit &lt;code&gt;cudaMalloc&lt;/code&gt; / &lt;code&gt;cudaMemcpy&lt;/code&gt; / &lt;code&gt;cudaFree&lt;/code&gt;. It lets both CPU and GPU use a single pointer, at the cost of some performance complexity under the hood.&lt;/p&gt;
&lt;p&gt;Unified Memory is seductive: it removes the need to think about host and device pointers separately. But it does not remove the physical reality that CPU and GPU memory are separate. Understanding when it helps and when it hurts is essential.&lt;/p&gt;</description></item><item><title>CUDA Reduction: Parallel Sum, Max, and Other Tree Algorithms</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-02-1-cuda-reduction/</link><pubDate>Wed, 02 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-02-1-cuda-reduction/</guid><description>&lt;h1 id="cuda-reduction-parallel-sum-max-and-other-tree-algorithms"&gt;CUDA Reduction: Parallel Sum, Max, and Other Tree Algorithms&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-09-01-2-cuda-occupancy"&gt;previous note&lt;/a&gt; covered occupancy. This note covers &lt;strong&gt;reduction&lt;/strong&gt;: taking a large array and producing a single value (a sum, max, min, product, or any associative binary operation). Reduction is one of the most important parallel algorithms on a GPU, and it teaches several key CUDA ideas at once: shared memory, thread cooperation, warp-level execution, and multi-kernel launches.&lt;/p&gt;
&lt;p&gt;This note builds the algorithm step by step, from a naive atomic version to a tree-based shared-memory reduction.&lt;/p&gt;</description></item><item><title>CUDA Streams and Host/Device Overlap</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-02-2-cuda-streams/</link><pubDate>Wed, 02 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-02-2-cuda-streams/</guid><description>&lt;h1 id="cuda-streams-and-hostdevice-overlap"&gt;CUDA Streams and Host/Device Overlap&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-09-02-1-cuda-reduction"&gt;previous note&lt;/a&gt; covered reduction, the first parallel algorithm on the GPU side. This note moves to the &lt;strong&gt;host-device boundary&lt;/strong&gt;: how to keep the GPU busy while the CPU prepares the next batch of data, and how to overlap data movement with computation.&lt;/p&gt;
&lt;p&gt;So far, every kernel launch and every &lt;code&gt;cudaMemcpy&lt;/code&gt; has been synchronous. The host waits, the GPU works, the host waits again. CUDA &lt;strong&gt;streams&lt;/strong&gt; let you break that pattern.&lt;/p&gt;</description></item><item><title>CUDA Occupancy: Filling the SM to Hide Latency</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-01-2-cuda-occupancy/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-01-2-cuda-occupancy/</guid><description>&lt;h1 id="cuda-occupancy-filling-the-sm-to-hide-latency"&gt;CUDA Occupancy: Filling the SM to Hide Latency&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-09-01-1-cuda-shared-memory-tiling"&gt;previous note&lt;/a&gt; showed how to use shared memory to fix uncoalesced access patterns. This note covers &lt;strong&gt;occupancy&lt;/strong&gt;: how many warps can live on an SM at the same time, and why that number determines whether the GPU can hide memory latency.&lt;/p&gt;
&lt;p&gt;Occupancy is the first CUDA performance topic that is not about memory access at all. It is about keeping the warp schedulers busy.&lt;/p&gt;</description></item><item><title>CUDA Shared Memory Tiling</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-09-01-1-cuda-shared-memory-tiling/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-09-01-1-cuda-shared-memory-tiling/</guid><description>&lt;h1 id="cuda-shared-memory-tiling"&gt;CUDA Shared Memory Tiling&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-08-30-3-cuda-memory-coalescing"&gt;previous note&lt;/a&gt; showed that coalesced memory access is the key to memory-bound kernel performance. But some algorithms naturally want uncoalesced access patterns. The fix is &lt;strong&gt;shared-memory tiling&lt;/strong&gt;: load data into fast on-chip SRAM in a coalesced way, rearrange it there, then write it back to global memory in a coalesced way.&lt;/p&gt;
&lt;p&gt;This note explains the tiling pattern, why &lt;code&gt;__syncthreads()&lt;/code&gt; is essential, the bank-conflict problem, and how to choose tile sizes.&lt;/p&gt;</description></item><item><title>CUDA Memory Coalescing: Why Access Patterns Matter</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-3-cuda-memory-coalescing/</link><pubDate>Sun, 30 Aug 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-3-cuda-memory-coalescing/</guid><description>&lt;h1 id="cuda-memory-coalescing-why-access-patterns-matter"&gt;CUDA Memory Coalescing: Why Access Patterns Matter&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-08-30-2-cuda-programming-model"&gt;previous note&lt;/a&gt; showed how to write and launch a CUDA kernel. This note answers the first performance question: why does the same kernel sometimes run 5× or 10× slower just because of how threads read memory?&lt;/p&gt;
&lt;p&gt;The answer is &lt;strong&gt;memory coalescing&lt;/strong&gt;. Because GPU memory is optimized for bandwidth over latency, the hardware rewards access patterns where threads in a warp read or write contiguous addresses together. If they do not, the GPU wastes bandwidth and cycles fetching data that most threads ignore.&lt;/p&gt;</description></item><item><title>CUDA Programming Model: Writing and Launching Kernels</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-2-cuda-programming-model/</link><pubDate>Sun, 30 Aug 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-2-cuda-programming-model/</guid><description>&lt;h1 id="cuda-programming-model-writing-and-launching-kernels"&gt;CUDA Programming Model: Writing and Launching Kernels&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-08-30-cuda-thread-hierarchy"&gt;previous note&lt;/a&gt; covered the hierarchy: thread, warp, block, grid, and how those map to SMs. This note turns that hierarchy into actual code. By the end, you will have seen a complete CUDA program, understood every line, and know how a host program hands work to the GPU.&lt;/p&gt;
&lt;p&gt;CUDA is an extension of C/C++. Most of the code you write is ordinary C++. A small number of CUDA-specific pieces — kernel functions, the launch syntax, a few memory APIs, and built-in thread indices — turn a sequential program into a massively parallel one.&lt;/p&gt;</description></item><item><title>CUDA Thread Hierarchy: Grids, Blocks, Warps, and Threads</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-1-cuda-thread-hierarchy/</link><pubDate>Sun, 30 Aug 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-08-30-1-cuda-thread-hierarchy/</guid><description>&lt;h1 id="cuda-thread-hierarchy-grids-blocks-warps-and-threads"&gt;CUDA Thread Hierarchy: Grids, Blocks, Warps, and Threads&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-08-29-anatomy-of-a-gpu"&gt;previous note&lt;/a&gt; mapped the hardware: SM, warp scheduler, register file, shared memory, L2, device memory. This note maps the &lt;em&gt;software abstraction&lt;/em&gt; CUDA exposes on top of that hardware. The two maps fit together almost one-to-one, and once you see how, most of CUDA stops being arbitrary syntax and becomes named hardware concepts.&lt;/p&gt;
&lt;p&gt;CUDA organizes parallel work into four nested levels:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Grid
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── Block (threads in a block can share fast on-chip memory, and sync)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── Warp (32 threads, executed in lockstep on the hardware)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── Thread (your kernel code, from one thread&amp;#39;s point of view)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This note works from the bottom up: start with the thread (the thing you actually program), then warp, then block, then grid, then show how the whole tower maps onto the GPU die.&lt;/p&gt;</description></item><item><title>Anatomy of a GPU: Hardware Components (NVIDIA)</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-08-29-anatomy-of-a-gpu/</link><pubDate>Sat, 29 Aug 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-08-29-anatomy-of-a-gpu/</guid><description>&lt;h1 id="anatomy-of-a-gpu-hardware-components"&gt;Anatomy of a GPU: Hardware Components&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/gpu/2026-08-29-cpu-vs-gpu"&gt;previous note&lt;/a&gt; covered &lt;em&gt;why&lt;/em&gt; GPUs look the way they do — throughput over latency, thousands of simple cores instead of a few smart ones. This note zooms into the actual silicon: what physically sits on a GPU die, what each piece is called, and what job it does. The goal is to have concrete hardware nouns (SM, warp scheduler, register file, L2, &amp;hellip;) in hand before those same nouns start showing up as CUDA concepts (&lt;code&gt;threadIdx&lt;/code&gt;, &lt;code&gt;__shared__&lt;/code&gt;, occupancy, &amp;hellip;).&lt;/p&gt;</description></item><item><title>CPU vs GPU Architecture</title><link>https://sankethbk.github.io/blog/posts/gpu/2026-08-29-cpu-vs-gpu/</link><pubDate>Sat, 29 Aug 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/gpu/2026-08-29-cpu-vs-gpu/</guid><description>&lt;h1 id="cpu-vs-gpu-architecture"&gt;CPU vs GPU Architecture&lt;/h1&gt;
&lt;h2 id="why-gpus-exist"&gt;Why GPUs exist&lt;/h2&gt;
&lt;p&gt;For decades, single-thread CPU performance improved &amp;ldquo;for free&amp;rdquo; — you write the same sequential code, and it runs faster on the next generation of chips, because clock speeds kept climbing.&lt;/p&gt;
&lt;p&gt;Around the mid-2000s, that stopped. Clock speeds hit a &lt;strong&gt;power wall&lt;/strong&gt; — you can&amp;rsquo;t keep cranking frequency without the chip melting. So the industry pivoted from &amp;ldquo;make one core faster&amp;rdquo; to &amp;ldquo;put more cores on the chip.&amp;rdquo; This is the multicore/manycore shift, and it&amp;rsquo;s the reason parallel programming stopped being a niche HPC skill and became something every programmer eventually runs into.&lt;/p&gt;</description></item></channel></rss>