<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://prabhavdogra.github.io/prabhav.tech/blog</id>
    <title>Hello! Blog</title>
    <updated>2025-04-19T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://prabhavdogra.github.io/prabhav.tech/blog"/>
    <subtitle>Hello! Blog</subtitle>
    <icon>https://prabhavdogra.github.io/prabhav.tech/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Digging into sync.Once: How Go Ensures One-Time Execution]]></title>
        <id>https://prabhavdogra.github.io/prabhav.tech/blog/sync_once</id>
        <link href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once"/>
        <updated>2025-04-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How it started?]]></summary>
        <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-it-started">How it started?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#how-it-started" class="hash-link" aria-label="Direct link to How it started?" title="Direct link to How it started?">​</a></h3>
<p>While writing some concurrent code for <a href="https://blinkit.com/" target="_blank" rel="noopener noreferrer">Blinkit</a>, I found myself reaching for <code>sync.Once</code>—a common utility in Go to ensure an action is performed just once, no matter how many goroutines attempt it. Out of curiosity, I decided to dig into how <code>sync.Once</code> works internally and how its implementation has evolved over time. While investigating the internals I came across something interesting and ended up contributing myself — a small step, but super rewarding!</p>
<p>In this blog, I’ll walk through the internals of <code>sync.Once</code>, how it leverages atomics for performance, and trace its evolution through Go versions. This blog is meant to motivate you to explore and solve your own doubts by diving into the source code of Go itself. You’ll be amazed at how much you can learn just by following the code and seeing how things work behind the scenes!</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="prerequisites-whats-synconce">Prerequisites: What's sync.Once?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#prerequisites-whats-synconce" class="hash-link" aria-label="Direct link to Prerequisites: What's sync.Once?" title="Direct link to Prerequisites: What's sync.Once?">​</a></h3>
<ul>
<li><code>sync.Once</code> ensures a function is only executed once, no matter how many times it's called, even across goroutines.</li>
<li>It's most commonly used to initialize shared resources like config, DB connections, or singletons.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	readConfigOnce  sync</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Once</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	config          </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Config</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">GetConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	readConfigOnce</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Do</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// Read yaml and make config object</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> config</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	cfg </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">LoadConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cfg</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Link to <a href="https://pkg.go.dev/sync#Once.Do" target="_blank" rel="noopener noreferrer">sync.Once documentation</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="digging-into-synconce-internals">Digging into sync.Once internals?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#digging-into-synconce-internals" class="hash-link" aria-label="Direct link to Digging into sync.Once internals?" title="Direct link to Digging into sync.Once internals?">​</a></h2>
<p>To follow along this read feel free to clone the <a href="https://github.com/golang/go" target="_blank" rel="noopener noreferrer">Golang</a> repository.</p>
<ul>
<li>Open the repository and run the bash script <code>./make.bash</code>, to build and install the latest compiler of Go.</li>
<li>Point your system or editor (like VSCode) to use the newly built Go version:</li>
</ul>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Bootstrapped Compilers</div><div class="admonitionContent_BuS1"><p>When I first came across the concept of a bootstrapped compiler, it honestly felt like a total brain teaser. The idea that a compiler could be written in the same language it’s supposed to compile? Wild.</p><p>Here’s the bombshell: <strong>the Go compiler is written in Go itself</strong>.
Sounds paradoxical, right?</p><p>Like a classic chicken-and-egg dilemma -
<strong>“How can a compiler compile itself if it doesn’t exist yet?”</strong></p><blockquote>
<p>In programming, bootstrapping refers to:
The process of building a system using a simpler or initial version of itself.</p>
</blockquote><ul>
<li><code>make.bash</code> is a shell script located at <code>src/make.bash</code> inside the Go source tree.</li>
<li>It's used to bootstrap the Go toolchain — it builds the Go compiler (<code>cmd/compile</code>), linker (<code>cmd/link</code>), and other core tools from scratch using the Go bootstrap toolchain.</li>
<li>It uses the already installed Go compiler</li>
<li>Use the clones Golang source code to build the new version of Go.</li>
</ul></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="internals-go-118">Internals (Go 1.18)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#internals-go-118" class="hash-link" aria-label="Direct link to Internals (Go 1.18)" title="Direct link to Internals (Go 1.18)">​</a></h3>
<p>Let's start from the basics, struct of <code>sync.Once</code> looks like</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/once.go | GOVERSION=1.18</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Once </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	done </span><span class="token builtin">uint32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	m    Mutex</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Pretty simple, right?</p>
<ul>
<li>One <code>uint32</code> flag <code>done</code>
<ul>
<li><code>done == 1</code> means that the function has ran once</li>
<li><code>done == 0</code> means that the function hasn't ran yet</li>
</ul>
</li>
<li>One mutex <code>m</code>
<ul>
<li>A mutex to avoid race condition while updating <code>done</code></li>
</ul>
</li>
</ul>
<p>Ok, somehow these two are used together to:</p>
<ul>
<li>Ensure that a particular action executes only once, regardless of how many times it is called concurrently.</li>
<li>Achieve this guarantee efficiently, minimizing lock contention for better performance.</li>
</ul>
<p>Ok so far so good right?</p>
<p>Let's move to the implementation of <code>once.Do(f)</code>: It ensures that the function <code>f()</code> is only executed once, no matter how many times it's called—even if from multiple goroutines.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/once.go | GOVERSION=1.18</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Once</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Do</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">f </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">LoadUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">doSlow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">f</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>Goal:</strong> Avoid acquiring a mutex unless absolutely necessary (i.e., the function <code>f()</code> hasn’t run yet).</p>
<ul>
<li><code>if atomic.LoadUint32(&amp;o.done) == 0</code>
<ul>
<li>We check if <code>done == 0</code>, <code>done == 0</code> means that the function hasn't ran yet</li>
<li>It checks <code>done == 0</code> atomically in one operation. More about <a href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations" target="_blank" rel="noopener noreferrer"><code>atomic package</code></a></li>
</ul>
</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Once</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">doSlow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">f </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">m</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Lock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">m</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Unlock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">done </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">StoreUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><code>if o.done == 0</code>
<ul>
<li>A second check inside the locked section.</li>
<li>Why? Because multiple goroutines might pass the atomic check in Do(), but only one should actually run the function. So we check again inside the lock to be 100% sure.</li>
<li>This is a double-checked locking pattern.</li>
</ul>
</li>
</ul>
<ul>
<li><code>defer atomic.StoreUint32(&amp;o.done, 1)</code>
<ul>
<li>Marks the function as executed after <code>f()</code> is done.</li>
<li>It’s deferred so even if <code>f()</code> panics, we still consider it “done” and don't call it again (intentional in Go’s design).</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="internals-go-124">Internals (Go 1.24)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#internals-go-124" class="hash-link" aria-label="Direct link to Internals (Go 1.24)" title="Direct link to Internals (Go 1.24)">​</a></h3>
<p>In newer versions of Go they revised the implementation of how <code>sync.Once</code>.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/once.go | GOVERSION=1.24</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Once </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> noCopy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	done atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Uint32</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	m    Mutex</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Ok!
What's changed now?</p>
<ul>
<li><code>noCopy</code> is embedded in <code>Once</code> struct</li>
<li>done is <code>atomic.Uint32</code> not <code>uint32</code></li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="nocopy-whats-that">"noCopy" What's that?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#nocopy-whats-that" class="hash-link" aria-label="Direct link to &quot;noCopy&quot; What's that?" title="Direct link to &quot;noCopy&quot; What's that?">​</a></h4>
<ul>
<li>It'a a zero-size struct that is adds no memory overhead.</li>
<li>Go has a statical analysis tool <code>go vet</code> that checks your Go source code for common mistakes and suspicious constructs that the compiler won’t catch.</li>
<li>Some types must never be copied once they’ve been initialized—most notably synchronization primitives like <code>sync.Mutex</code>, <code>sync.Once</code>, etc. Accidental copies can lead to deadlocks or data races.</li>
<li>Having <code>noCopy</code> embedded in your struct will produce a warning if your type is ever copied by <code>go vet</code>.</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="regular-uint32-vs-atomicuint32">Regular uint32 vs. atomic.Uint32<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#regular-uint32-vs-atomicuint32" class="hash-link" aria-label="Direct link to Regular uint32 vs. atomic.Uint32" title="Direct link to Regular uint32 vs. atomic.Uint32">​</a></h4>
<p>When you don't know something in Go let's follow the approach like we have done, and let's look at the source code:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/atomic/type.go | GOVERSION=1.24</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Uint32 </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> noCopy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	v </span><span class="token builtin">uint32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Ok, wow! As you can see <code>atomic.Uint32</code> is just a wrapper type around a uint32 with <code>noCopy</code> but why???</li>
</ul>
<p>Let's look further functions binded to this struct:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Load atomically loads and returns the value stored in x.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">uint32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">LoadUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Store atomically stores val into x.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Store</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">val </span><span class="token builtin">uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">StoreUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> val</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Swap atomically stores new into x and returns the previous value.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Swap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">new</span><span class="token plain"> </span><span class="token builtin">uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">old </span><span class="token builtin">uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">SwapUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">new</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// CompareAndSwap executes the compare-and-swap operation for x.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CompareAndSwap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">old</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">new</span><span class="token plain"> </span><span class="token builtin">uint32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">swapped </span><span class="token builtin">bool</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CompareAndSwapUint32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> old</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">new</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Ok, seems like it's just a wrapper type provides methods for atomic operations.</p>
<p>And that is exactly what <code>atomic.Uint32</code> is:</p>
<blockquote>
<p>A Go&nbsp;1.19+ wrapper type around a uint32 that provides methods for atomic operations</p>
</blockquote>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="bonus-go-125-hopefully">Bonus: Go. 1.25 (Hopefully)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#bonus-go-125-hopefully" class="hash-link" aria-label="Direct link to Bonus: Go. 1.25 (Hopefully)" title="Direct link to Bonus: Go. 1.25 (Hopefully)">​</a></h3>
<p>While exploring the internals of <code>sync.Once</code>, I noticed that the done field — which indicates whether the function has already been executed — was originally an <code>atomic.Uint32</code>.</p>
<p>However, since it’s only ever used as a boolean flag (0 or 1), I realized it could be more semantically clear to use <code>atomic.Bool</code> instead. Even though atomic.Bool is just a thin wrapper around a uint32 under the hood, switching to it makes the code more self-explanatory and aligns better with the intent of the field.
So I decided to raise a PR and it got merged <code>:)</code></p>
<p>Now the struct looks like this:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/once.go | GOVERSION=1.25</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Once </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> noCopy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	done atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Bool</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	m    Mutex</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://prabhavdogra.github.io/prabhav.tech/blog/sync_once#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Exploring <code>sync.Once</code> from <strong>Go&nbsp;1.18</strong> to <strong>Go&nbsp;1.25</strong> shows how a small, fundamental primitive can evolve for clarity, safety, and maintainability:</p>
<ul>
<li><strong>Go&nbsp;1.18</strong>
<ul>
<li>Used a plain uint32 flag plus a Mutex and double‑checked locking</li>
<li>Minimized lock contention by atomically checking the flag on the fast path</li>
</ul>
</li>
</ul>
<ul>
<li>
<p><strong>Go&nbsp;1.24</strong></p>
<ul>
<li>Embeds <code>noCopy</code> to catch accidental copies via go vet</li>
<li>Switches to <code>atomic.Uint32</code>, providing a clean, method‑based API</li>
</ul>
</li>
<li>
<p><strong>Go&nbsp;1.25</strong></p>
<ul>
<li>Switches <code>atomic.Uint32</code> to <code>atomic.Bool</code></li>
</ul>
</li>
</ul>
<p>Along the way we’ve seen:</p>
<ul>
<li><strong>Bootstrapping</strong> – how Go builds itself from source via make.bash</li>
<li><strong>Atomic vs. mutex</strong> – why lock‑free fast paths matter in high‑concurrency code</li>
<li><strong>Static analysis</strong> – how noCopy and go vet help prevent subtle bugs</li>
</ul>
<p>The beauty of Go’s standard library is that it balances performance, safety, and readability. Whenever you have a question about how Go works under the hood, the answer is just a GitHub clone and a make.bash away. Dive into the source, follow the code, and you’ll not only solve your doubts—you’ll discover deeper principles that make Go such a pleasure to work with.</p>
<p>And it’s downright fun to see how these technologies evolve over time.</p>]]></content>
        <author>
            <name>Prabhav Dogra</name>
            <uri>https://github.com/prabhavdogra</uri>
        </author>
        <category label="Go" term="Go"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[What does memory mean actually?]]></title>
        <id>https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy</id>
        <link href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy"/>
        <updated>2025-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Introduction]]></summary>
        <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h3>
<p>While exploring how Go manages memory, I stumbled upon an intricate hierarchy that determines how fast data moves between the CPU and RAM. Go’s runtime optimizations, like garbage collection and stack allocation, made me curious about what happens under the hood. This led me to registers, caches (L1, L2, L3), and RAM—each playing a crucial role in balancing speed and storage.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="prerequisites-whats-a-cpu-cycle">Prerequisites: What's a CPU Cycle?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#prerequisites-whats-a-cpu-cycle" class="hash-link" aria-label="Direct link to Prerequisites: What's a CPU Cycle?" title="Direct link to Prerequisites: What's a CPU Cycle?">​</a></h2>
<p><strong>CPU Cycle:</strong></p>
<ul>
<li>It's the smallest unit of processing that a CPU can do.</li>
<li>Each cycle allows the CPU to execute instructions like fetching data, performing arithmetic, or storing results.</li>
<li>For example: the method <code>atomic.CompareAndSwap</code> in go is executed as follows:<!-- -->
<ul>
<li>It reads a value from memory.</li>
<li>It compares it with an expected value.</li>
<li>If they match, it writes a new value.</li>
<li>This requires at least three steps (read, compare, write), which take multiple cycles.</li>
</ul>
</li>
<li>A single 1GHz CPU can complete one CPU cycle in 1 nanosecond.</li>
<li>Similarly, a 3GHz CPU can complete one CPU cycle in 0.33 nanoseconds.</li>
<li>Not every operation takes 1 cycle<!-- -->
<ul>
<li>Simple instructions like integer addition (a + b) may take 1 cycle.</li>
<li>More complex operations (e.g., division, memory access) can take multiple cycles.</li>
</ul>
</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Clock edge" src="data:image/png;base64,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" width="616" height="202" class="img_ev3q"></p>
<p><strong>NOTE:</strong> Here <strong>Period = Clock Cycle</strong></p>
<p><strong>Clock edge</strong>
A clock edge refers to the transition point of a clock signal where changes in a digital circuit occur. The clock signal is a periodic waveform (square wave), and it has two main edges:</p>
<ul>
<li><strong>Rising Edge (Positive Edge)</strong>
<ul>
<li>The transition from low (0) to high (1).</li>
<li>Many digital circuits, including registers and flip-flops, are designed to capture input and update their state on this edge.</li>
</ul>
</li>
<li><strong>Falling Edge (Negative Edge)</strong>
<ul>
<li>The transition from high (1) to low (0).</li>
<li>Some circuits use this edge for synchronization, though it is less common than the rising edge.</li>
</ul>
</li>
</ul>
<p><strong>Why is the Clock Edge Important?</strong></p>
<ul>
<li>It synchronizes operations in digital circuits.</li>
<li>Registers and flip-flops capture and store data only on a specific edge, ensuring controlled data flow.</li>
<li>In CPU pipelines, clock edges trigger different stages like instruction fetch, decode, execute, etc.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="understanding-computer-memory-hierarchy">Understanding Computer Memory Hierarchy<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#understanding-computer-memory-hierarchy" class="hash-link" aria-label="Direct link to Understanding Computer Memory Hierarchy" title="Direct link to Understanding Computer Memory Hierarchy">​</a></h2>
<ol>
<li><strong>Registers (Fastest, Smallest)</strong>
<ul>
<li>Located inside the CPU, closest to the execution units.</li>
<li>Stores data for immediate operations (e.g., arithmetic calculations).</li>
<li>Extremely small (few bytes) but operates at CPU clock speed.</li>
<li><strong>Access time:</strong> 1 CPU cycle (fastest).</li>
</ul>
</li>
<li><strong>L1 Cache (Level 1)</strong>
<ul>
<li>Smallest and fastest cache (typically 32KB to 128KB per core).</li>
<li>Directly integrated into the CPU core.</li>
<li>Stores frequently used instructions (will discuss this later) and data for ultrafast access.</li>
<li><strong>Access time:</strong> 2-4 CPU cycles.</li>
</ul>
</li>
<li><strong>L2 Cache (Level 2)</strong>
<ul>
<li>Larger than L1 (256KB to a few MB per core).</li>
<li>Slightly slower than L1 but still much faster than RAM.</li>
<li>Used to store recently accessed data that might be needed again soon.</li>
<li><strong>Access time:</strong> 10-20 CPU cycles.</li>
</ul>
</li>
<li><strong>L3 Cache (Level 3)</strong>
<ul>
<li>Shared among multiple CPU cores, ranging from a few MB to tens of MB.</li>
<li>Acts as a buffer between L2 and RAM, reducing latency for core-to-core communication.</li>
<li><strong>Access time:</strong> 30-60 CPU cycles.</li>
</ul>
</li>
<li><strong>RAM (Random Access Memory)</strong>
<ul>
<li>Main working memory for the system (GBs in size).</li>
<li>Much slower than CPU caches but holds more data.</li>
<li>Stores active processes and data that aren’t frequently used by the CPU.</li>
<li><strong>Access time:</strong> 100+ CPU cycles.</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="registers-the-fastest-storage">Registers: The Fastest Storage<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#registers-the-fastest-storage" class="hash-link" aria-label="Direct link to Registers: The Fastest Storage" title="Direct link to Registers: The Fastest Storage">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-are-registers">What Are Registers?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#what-are-registers" class="hash-link" aria-label="Direct link to What Are Registers?" title="Direct link to What Are Registers?">​</a></h3>
<p>Registers are ultra-fast, small storage units embedded directly inside a computer’s CPU (Central Processing Unit). They are temporary holding areas for data, instructions, or memory addresses that the CPU needs to access immediately during computations. Registers are the fastest type of memory in a computer, designed to minimize delays in processing.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-registers-work">How Registers Work?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#how-registers-work" class="hash-link" aria-label="Direct link to How Registers Work?" title="Direct link to How Registers Work?">​</a></h3>
<ul>
<li><strong>Fetching Data:</strong> When the CPU needs to perform an operation (e.g., 5 + 3), it first copies the values 5 and 3 from RAM into two registers.</li>
<li><strong>Processing:</strong> The CPU’s arithmetic logic unit (ALU) performs the addition directly using the values stored in the registers.</li>
<li><strong>Storing Results:</strong> The result (8) is placed into another register, which can either be used for further operations or written back to RAM.</li>
</ul>
<ol>
<li>
<p><strong>Basic Structure: Flip-Flops</strong></p>
<ul>
<li><strong>Core Component:</strong> Registers are built using D-type flip-flops, each flip-flop just stores one bit. A 32-bit register, for example, contains 32 flip-flops.</li>
<li><strong>Function:</strong> Each flip-flop has:<!-- -->
<ul>
<li><strong>Data Input (D):</strong> Receives the bit to store.</li>
<li><strong>Write Enable (WE):</strong> Controls whether the flip-flop should capture and store the input value on the next active clock edge.</li>
<li><strong>Clock Input (CLK):</strong> Provides the timing signal that synchronizes when data is captured by the flip-flop. The flip-flop updates its value on the rising edge of the clock.</li>
<li><strong>Output (Q):</strong> Provides the stored bit.</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Data Storage and Clock Synchronization</strong></p>
<p><strong>Writing Data:</strong></p>
<ul>
<li>When the CPU writes to a register:<!-- -->
<ul>
<li>The write enable signal for the register is activated.</li>
<li>Data is placed on the <strong>input bus</strong>.  The input bus is a set of electrical connections that carry data to the register.</li>
<li>In the <strong>next rising edge of the clock</strong>, the flip-flops capture the input values.</li>
</ul>
</li>
</ul>
<p><strong>Reading Data:</strong></p>
<ol>
<li><strong>Stored Data in Flip-Flops</strong>
<ul>
<li>A register consists of multiple flip-flops, each storing a single bit. Once a value is stored in a flip-flop, it remains available at its output until changed by a new write operation. However, this stored value is not automatically placed on the CPU’s internal bus—something must send the data when the data is read.</li>
<li>Each flip-flop's output is connected to a tri-state buffer, which controls whether the stored bit is driven onto the bus connecting CPU and register (for reading the bit).</li>
</ul>
</li>
<li><strong>Role of the Tri-State Buffer</strong>
<ul>
<li>Tri-State Buffer ensures conflict-free (kindof like mutex) data access, enabling the CPU to perform billions of operations per second reliably.</li>
<li>A tri-state buffer is a special circuit that can either:<!-- -->
<ul>
<li><strong>Tri-State Buffer Enabled:</strong> Passes the stored data from the register to the bus connecting CPU and register.</li>
<li><strong>Tri-State Buffer Disabled:</strong> Disconnects the register from bus connecting CPU and register.</li>
</ul>
</li>
<li>This is necessary because multiple registers share the same internal bus, and only one should be active at a time to avoid conflicting reads and writes (more of a hardware constraint).</li>
<li>The enable signal is synchronized with the CPU clock to ensure stable data transfer.</li>
</ul>
</li>
</ol>
</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="types-of-registers-a-little-extra-context">Types of Registers (A little extra context)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#types-of-registers-a-little-extra-context" class="hash-link" aria-label="Direct link to Types of Registers (A little extra context)" title="Direct link to Types of Registers (A little extra context)">​</a></h3>
<ul>
<li><strong>General-Purpose Registers:</strong>
<ul>
<li>Used for temporary data storage and most calculations.</li>
</ul>
</li>
<li><strong>Special-Purpose Registers:</strong>
<ul>
<li><strong>Program Counter (PC):</strong> Holds the memory address of the next instruction to execute.</li>
<li><strong>Instruction Register (IR):</strong> Stores the current instruction being decoded/executed.</li>
<li><strong>Stack Pointer (SP)</strong>: Tracks the top of the stack in memory.</li>
<li><strong>Status/Flag Register</strong>: Stores metadata about operations (e.g., whether a result was zero or caused an overflow).</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-registers-are-essential">Why Registers Are Essential<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#why-registers-are-essential" class="hash-link" aria-label="Direct link to Why Registers Are Essential" title="Direct link to Why Registers Are Essential">​</a></h3>
<ul>
<li><strong>Eliminate Bottlenecks:</strong> Without registers, the CPU would need to read/write data directly from RAM for every operation, which is too slow.</li>
<li><strong>Enable Pipelining:</strong> Registers allow the CPU to work on multiple instructions simultaneously by holding intermediate states.</li>
<li><strong>Direct Hardware Access:</strong> Registers interface directly with the CPU’s ALU and control unit, enabling rapid execution of machine-level instructions.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="cpu-cache-l1-l2-l3-cpu-caches">CPU Cache: L1, L2, L3 CPU caches<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#cpu-cache-l1-l2-l3-cpu-caches" class="hash-link" aria-label="Direct link to CPU Cache: L1, L2, L3 CPU caches" title="Direct link to CPU Cache: L1, L2, L3 CPU caches">​</a></h2>
<p>CPU Caches are small, ultra-fast memory layers between the CPU and main memory (RAM). They store frequently accessed data and instructions to reduce latency and improve performance. Modern CPUs use three levels of cache:</p>
<p>There are two types of cached instructions:</p>
<ul>
<li><strong>Instruction Cache:</strong>
<ul>
<li><strong>What it stores:</strong>
<ul>
<li>Instructions are the actual binary code (machine code) of the program being executed by the CPU.</li>
<li>Examples: <code>ADD</code>, <code>MOV</code>, <code>JUMP</code>, <code>LOAD</code>, or any operation the CPU performs.</li>
</ul>
</li>
<li><strong>Purpose:</strong>
<ul>
<li>Allows the CPU to quickly fetch the next operation to execute.</li>
<li>For example, when running a loop, the instruction cache holds the repeated code (<code>for</code>, <code>while</code> loops) so the CPU doesn’t have to fetch it repeatedly from slower memory.</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><strong>Data Cache:</strong>
<ul>
<li><strong>What it stores:</strong>
<ul>
<li>Data refers to the values the CPU is actively working with.</li>
<li>Examples: Variables (e.g., int x = 5), memory addresses, temporary results, or input/output values.</li>
</ul>
</li>
<li><strong>Purpose:</strong>
<ul>
<li>Provides fast access to the operands (numbers, addresses) needed by instructions.</li>
<li>For example, when calculating x + y, the data cache holds the values of x and y for the ADD instruction to use.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>Why Split Them?</strong></p>
<ul>
<li><strong>Parallel Access:</strong>
<ul>
<li>The CPU can fetch the next instruction (from the instruction cache) while simultaneously reading/writing data (from the data cache). This avoids bottlenecks.</li>
<li><strong>Example:</strong> While executing an ADD instruction, the CPU can already fetch the next instruction (MOV or JUMP) from the instruction cache.</li>
</ul>
</li>
<li><strong>Specialization:</strong>
<ul>
<li>Instruction caches are optimized for sequential access (program code is usually read in order).</li>
<li>Data caches are optimized for random access (variables can be accessed in any order).</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="l1-cache-level-1-cache">L1 Cache (Level 1 Cache)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#l1-cache-level-1-cache" class="hash-link" aria-label="Direct link to L1 Cache (Level 1 Cache)" title="Direct link to L1 Cache (Level 1 Cache)">​</a></h3>
<ul>
<li><strong>Role:</strong>
<ul>
<li>The fastest and smallest cache, directly integrated into the CPU core.</li>
<li>Split into L1 Instruction Cache (stores executable code) and L1 Data Cache (stores data).</li>
</ul>
</li>
<li><strong>Characteristics:</strong>
<ul>
<li><strong>Size:</strong> Typically 32–64 KB per core (e.g., 64 KB total: 32 KB data + 32 KB instructions).</li>
<li><strong>Speed:</strong> 1–4 clock cycles access time (fastest).</li>
<li><strong>Location:</strong> Embedded within each CPU core.</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="l2-cache-level-2-cache">L2 Cache (Level 2 Cache)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#l2-cache-level-2-cache" class="hash-link" aria-label="Direct link to L2 Cache (Level 2 Cache)" title="Direct link to L2 Cache (Level 2 Cache)">​</a></h3>
<ul>
<li><strong>Role:</strong>
<ul>
<li>Acts as a middle layer between L1 and L3.</li>
<li>Stores data/instructions not held in L1 but likely to be reused.</li>
</ul>
</li>
<li><strong>Characteristics:</strong>
<ul>
<li><strong>Size:</strong> 256 KB–2 MB per core (varies by CPU design).</li>
<li><strong>Speed</strong>: 10–20 clock cycles access time.</li>
<li><strong>Location</strong>: May be shared between cores or dedicated per core (e.g., AMD Zen vs. Intel Core).</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="l3-cache-level-3-cache">L3 Cache (Level 3 Cache)<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#l3-cache-level-3-cache" class="hash-link" aria-label="Direct link to L3 Cache (Level 3 Cache)" title="Direct link to L3 Cache (Level 3 Cache)">​</a></h3>
<ul>
<li><strong>Role:</strong>
<ul>
<li>The largest and slowest CPU cache, shared across all cores.</li>
<li>Reduces traffic to RAM by storing data shared between multiple cores.</li>
</ul>
</li>
<li><strong>Characteristics</strong>:<!-- -->
<ul>
<li><strong>Size</strong>: 4–64 MB</li>
<li><strong>Speed</strong>: 20–50 clock cycles access time.</li>
<li><strong>Location</strong>: On the CPU die but outside individual cores.</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-three-levels">Why Three Levels?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#why-three-levels" class="hash-link" aria-label="Direct link to Why Three Levels?" title="Direct link to Why Three Levels?">​</a></h3>
<ul>
<li><strong>Latency vs. Size Trade-off:</strong> L1 prioritizes speed for critical data, L2 balances speed and size, and L3 minimizes RAM access.</li>
<li><strong>Efficiency:</strong> Reduces "cache misses" by filtering requests through layers (90% of data is often found in L1/L2).</li>
<li><strong>Multicore Optimization:</strong> L3 enables shared data (e.g., game textures, OS tasks) to stay accessible to all cores.</li>
</ul>
<p><strong>Practical Example:</strong></p>
<ul>
<li>When running a game:<!-- -->
<ul>
<li>L1: Stores code for rendering a character (e.g., position calculations).</li>
<li>L2: Caches textures used in the current scene.</li>
<li>L3: Holds shared assets like audio files or global physics data.</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-not-replace-l2-and-l3-with-l1">Why not replace L2 and L3 with L1?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#why-not-replace-l2-and-l3-with-l1" class="hash-link" aria-label="Direct link to Why not replace L2 and L3 with L1?" title="Direct link to Why not replace L2 and L3 with L1?">​</a></h3>
<ul>
<li><strong>Physical Limits:</strong>
<ul>
<li>L1 is fast but bulky/power-hungry. Scaling it to L2/L3 sizes would make CPUs impractical (cost, heat, latency).</li>
</ul>
</li>
<li><strong>Hierarchy Efficiency</strong>:<!-- -->
<ul>
<li><strong>L1</strong>: Speed-optimized for critical data.</li>
<li><strong>L2</strong>: Balances size/speed for common data.</li>
<li><strong>L3</strong>: Shared, large storage to minimize RAM trips.</li>
</ul>
</li>
<li><strong>Cache Miss Mitigation</strong>:<!-- -->
<ul>
<li>Without L2/L3, frequent RAM access (~100x slower) would cripple performance.</li>
</ul>
</li>
<li><strong>Power/Heat</strong>:<!-- -->
<ul>
<li>Larger L1 would drain power and overheat CPUs.</li>
</ul>
</li>
<li><strong>Multicore Sharing</strong>:<!-- -->
<ul>
<li>L3 allows cores to access shared data without duplicating it in L1/L2.</li>
</ul>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="ram-the-parts-of-the-memory-cell">RAM: The Parts of the Memory Cell<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#ram-the-parts-of-the-memory-cell" class="hash-link" aria-label="Direct link to RAM: The Parts of the Memory Cell" title="Direct link to RAM: The Parts of the Memory Cell">​</a></h2>
<p>Imagine a single memory cell in your computer’s RAM (the temporary memory your computer uses to do stuff). Think of it like a tiny light switch and a tiny battery working together to store a 0 or a 1 (the basic "yes/no" language computers use). Here’s how it works:</p>
<ul>
<li><strong>Capacitor:</strong> A tiny “battery” that can hold an electric charge.<!-- -->
<ul>
<li>Charged (has electricity) = 1</li>
<li>Not charged (empty) = 0</li>
</ul>
</li>
<li><strong>Transistor:</strong> A tiny “light switch” that controls access to the capacitor.<!-- -->
<ul>
<li>ON (switch closed) = Lets electricity flow.</li>
<li>OFF (switch open) = Blocks electricity.</li>
</ul>
</li>
<li><strong>Address Line:</strong> The wire that tells the transistor to turn ON/OFF.</li>
<li><strong>Data Line:</strong> The wire that reads or writes the charge (0 or 1) to the capacitor.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-it-works">How It Works<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#how-it-works" class="hash-link" aria-label="Direct link to How It Works" title="Direct link to How It Works">​</a></h3>
<ol>
<li>Writing Data (Saving a 0 or 1)<!-- -->
<ul>
<li><strong>Step 1:</strong> The CPU (computer’s brain) says, “Hey, I need to save a 1 at this specific memory cell!”</li>
<li><strong>Step 2:</strong> The Address Line sends electricity (like flipping the switch ON).</li>
<li><strong>Step 3:</strong> The Data Line sends electricity to charge the capacitor (filling the tiny battery).
<strong>Result:</strong> Capacitor is charged = 1 is stored.
If the CPU wants to save a 0, the Data Line drains the capacitor instead.</li>
</ul>
</li>
<li>Reading Data (Checking if it’s 0 or 1)<!-- -->
<ul>
<li><strong>Step 1:</strong> The CPU says, “What’s stored at this memory cell?”</li>
<li><strong>Step 2:</strong> The Address Line sends electricity (switch ON).</li>
<li><strong>Step 3:</strong> If the capacitor is charged (storing 1), electricity flows out through the Data Line.<!-- -->
<ul>
<li><strong>Result:</strong> The CPU detects this flow = 1.</li>
</ul>
</li>
<li><strong>Step 4:</strong> If the capacitor is empty (storing 0), no electricity flows.<!-- -->
<ul>
<li><strong>Result:</strong> The CPU detects no flow = 0.</li>
</ul>
</li>
</ul>
</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="refresh-cycle">Refresh Cycle<a href="https://prabhavdogra.github.io/prabhav.tech/blog/memory_hierarchy#refresh-cycle" class="hash-link" aria-label="Direct link to Refresh Cycle" title="Direct link to Refresh Cycle">​</a></h3>
<ul>
<li>Each DRAM cell consists of a <strong>capacitor (storing a 1 or 0 as charge)</strong> and an <strong>access transistor</strong>.</li>
<li>When a cell is <strong>“charged” (1)</strong> or <strong>“discharged” (0)</strong>, that state is maintained only temporarily because the charge leaks away.</li>
<li>The <strong>DRAM controller (or memory controller)</strong> periodically reads each memory cell and then rewrites (recharges) it to restore the original value. This <strong>refresh cycle</strong> typically occurs every 64–128 milliseconds for all cells.</li>
<li>Without refreshing, the leakage would eventually cause the stored bits to flip, leading to data corruption. The periodic refresh ensures data integrity over time.</li>
</ul>]]></content>
        <author>
            <name>Prabhav Dogra</name>
            <uri>https://github.com/prabhavdogra</uri>
        </author>
        <category label="Go" term="Go"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Writing your own Goroutines]]></title>
        <id>https://prabhavdogra.github.io/prabhav.tech/blog/diy_goroutines</id>
        <link href="https://prabhavdogra.github.io/prabhav.tech/blog/diy_goroutines"/>
        <updated>2025-03-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This all started when someone asked me how goroutines work internally and all I could respond with was:]]></summary>
        <content type="html"><![CDATA[<p>This all started when someone asked me how goroutines work internally and all I could respond with was:</p>
<blockquote>
<p>"Goroutines are lightweight threads managed by the Go runtime instead of the operating system. Go runtime automatically multiplexes—mapping multiple goroutines onto a smaller number of OS threads. And that somehow makes them fast?? 👉👈"</p>
</blockquote>
<p>If anyone asked me any in-depth questions about how this multiplexing worked I was blank. So I decided to gain a deeper understanding by implementing goroutines myself. Cloned the <a href="https://github.com/golang/go" target="_blank" rel="noopener noreferrer">Go Github repo</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="to-be-continued">To be continued...<a href="https://prabhavdogra.github.io/prabhav.tech/blog/diy_goroutines#to-be-continued" class="hash-link" aria-label="Direct link to To be continued..." title="Direct link to To be continued...">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="references">References<a href="https://prabhavdogra.github.io/prabhav.tech/blog/diy_goroutines#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h3>
<ul>
<li>Goroutines and their scheduling basics:<!-- -->
<ul>
<li><a href="https://www.youtube.com/watch?v=S-MaTH8WpOM" target="_blank" rel="noopener noreferrer">https://www.youtube.com/watch?v=S-MaTH8WpOM</a> [Goroutines: Vicki Niu]</li>
<li><a href="https://youtu.be/MYtUOOizITs?si=FVGFtez2z3fNCjx7" target="_blank" rel="noopener noreferrer">https://youtu.be/MYtUOOizITs?si=FVGFtez2z3fNCjx7</a> [Goroutines: jesus espino]</li>
<li><a href="https://youtu.be/wQpC99Xu1U4?si=uOu0RiLyMpNXKYa0" target="_blank" rel="noopener noreferrer">https://youtu.be/wQpC99Xu1U4?si=uOu0RiLyMpNXKYa0</a> [Go Scheduler: Madhav Jivrajani]</li>
</ul>
</li>
<li>Go scheduler basics<!-- -->
<ul>
<li>Channel primitives: <a href="https://youtu.be/KBZlN0izeiY?si=8HAeSVJxE3Vc3GC0" target="_blank" rel="noopener noreferrer">https://youtu.be/KBZlN0izeiY?si=8HAeSVJxE3Vc3GC0</a> [Channels - Kavya Joshi]</li>
</ul>
</li>
<li>How memory allocation works in go<!-- -->
<ul>
<li><a href="https://goog-perftools.sourceforge.net/doc/tcmalloc.html" target="_blank" rel="noopener noreferrer">https://goog-perftools.sourceforge.net/doc/tcmalloc.html</a> [tcmalloc]</li>
<li><a href="https://andrestc.com/post/go-memory-allocation-pt1/" target="_blank" rel="noopener noreferrer">https://andrestc.com/post/go-memory-allocation-pt1/</a> [tcmalloc inspired allocator]</li>
</ul>
</li>
<li>Go garbage collection internals:<!-- -->
<ul>
<li><a href="https://youtu.be/gPxFOMuhnUU?si=O9pn99sLiqptgyw3" target="_blank" rel="noopener noreferrer">https://youtu.be/gPxFOMuhnUU?si=O9pn99sLiqptgyw3</a> [Garbage collector: Maya Rosecrance]</li>
<li><a href="https://youtu.be/We-8RSk4eZA?si=QNXxqq2xVEoh9At9" target="_blank" rel="noopener noreferrer">https://youtu.be/We-8RSk4eZA?si=QNXxqq2xVEoh9At9</a> [GC Pacer: Madhav Jivrajani]</li>
</ul>
</li>
<li>Netpoll: <a href="https://youtu.be/xwlo3xigknI?si=dmTrK_CH_fa0Bs51" target="_blank" rel="noopener noreferrer">https://youtu.be/xwlo3xigknI?si=dmTrK_CH_fa0Bs51</a> [netpoll - Cindy Sridharan]</li>
</ul>]]></content>
        <author>
            <name>Prabhav Dogra</name>
            <uri>https://github.com/prabhavdogra</uri>
        </author>
        <category label="Go" term="Go"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[How Go atomic operations avoid race conditions?]]></title>
        <id>https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations</id>
        <link href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations"/>
        <updated>2025-02-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Introduction]]></summary>
        <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction<a href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h3>
<p>This question popped up in my head, <em>"How Go atomic operations avoid race conditions?"</em></p>
<p>I finally gathered the courage to open the cloned <a href="https://github.com/golang/go" target="_blank" rel="noopener noreferrer">Go Github repo</a> and scan through it.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="go-code-structure">Go Code Structure<a href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations#go-code-structure" class="hash-link" aria-label="Direct link to Go Code Structure" title="Direct link to Go Code Structure">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Go code structure" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/go_structure-7a1da1e54c9b5a7c7c73d3360e7c4c52.png" width="614" height="491" class="img_ev3q"></p>
<p><em>Source: ChatGPT</em></p>
<p>I went inside the implementation of <code>CompareAndSwapInt32</code> and found this:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/atomic/doc.go</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Consider using the more ergonomic and less error-prone [Int32.CompareAndSwap] instead.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//go:noescape</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CompareAndSwapInt32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">addr </span><span class="token operator" style="color:#393A34">*</span><span class="token builtin">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> old</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">new</span><span class="token plain"> </span><span class="token builtin">int32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">swapped </span><span class="token builtin">bool</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Finding the implementation of this was not straightforward, because this method is implemented in Go Assembly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/sync/atomic/asm.s</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">TEXT ·</span><span class="token function" style="color:#d73a49">CompareAndSwapInt32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">SB</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">NOSPLIT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">$</span><span class="token number" style="color:#36acaa">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	JMP	internal∕runtime∕atomic·</span><span class="token function" style="color:#d73a49">Cas</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">SB</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="whats-go-assembly">What's Go Assembly?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations#whats-go-assembly" class="hash-link" aria-label="Direct link to What's Go Assembly?" title="Direct link to What's Go Assembly?">​</a></h3>
<p>Simply put, <strong>Go Assembly</strong> is the low-level language used to write performance-critical functions in Go.
<strong>Go Assembler</strong> (Code directory path: cmd/asm) is the tool that compiles <strong>Go assembly (.s) files</strong> into machine code.
The Go assembler was heavily inspired by the <a href="https://9p.io/sys/doc/compiler.html" target="_blank" rel="noopener noreferrer">Plan 9 C compilers</a>.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Plan 9 C compilers</div><div class="admonitionContent_BuS1"><p><strong>Plan 9 C compilers (6c, 8c, 5c, etc.)</strong> were architecture-specific compilers designed to generate optimized code for different CPU architectures. Unlike GCC or LLVM, which support multiple architectures within a single compiler framework, Plan 9 used separate compilers for different instruction sets. These compilers were originally developed for the Plan 9 operating system, an experimental OS designed as a potential successor to Unix-based systems.</p><p>You can read more about it here: <a href="https://9p.io/sys/doc/compiler.html" target="_blank" rel="noopener noreferrer">https://9p.io/sys/doc/compiler.html</a></p></div></div>
<p>Go drew inspiration from 9 C Compiler:</p>
<ul>
<li>Just like <strong>Plan 9</strong> had <strong>separate compilers</strong> for <strong>different architectures</strong> (e.g., 6c for x86-64, 8c for ARM, etc.).</li>
<li>Go’s assembler follows a similar architecture-based approach, instead of a universal assembler Go has different assemblers for x86, ARM, RISC-V, etc.</li>
</ul>
<p>You can watch this, an interesting talk about <a href="https://www.youtube.com/watch?v=KINIAgRpkDA" target="_blank" rel="noopener noreferrer">Go Assembler</a> presented by Rob Pike himself.</p>
<p><a href="https://go.dev/doc/asm" target="_blank" rel="noopener noreferrer">Go Assembler Documentation</a></p>
<p>Go Assembler streamlined a lot of things:</p>
<ul>
<li><strong>Portability:</strong> It abstracts CPU architecture details better.</li>
<li><strong>Simpler syntax:</strong> No need for % prefixes, brackets, or complex addressing.</li>
<li><strong>Unified across architectures:</strong> ARM, AMD64, RISC-V, etc., use the same structure.</li>
<li><strong>Designed for the Go runtime:</strong> Helps implement Go features like garbage collection, goroutines, and stack growth efficiently.</li>
</ul>
<p>Go Assembler has 4 architecture-specific implementations of <code>atomic.CompareAndSwapInt32()</code>:</p>
<ul>
<li><strong>amd64.s</strong>: For AMD64 (x86-64) architecture (Intel, AMD CPUs).</li>
<li><strong>arm64.s:</strong> For ARM64 (AArch64) processors (used in Apple M1/M2, mobile devices, servers).</li>
<li><strong>ppc64le.s:</strong> For PowerPC 64-bit, Little Endian (used in IBM systems).</li>
<li><strong>s390x.s:</strong> For IBM Z-series mainframes (used in enterprise computing).</li>
</ul>
<p>Go runs on multiple architectures, and low-level atomic operations must be natively implemented for each to ensure compatibility.</p>
<p>Added the implementations for one architecture (other 3 are similar) in Go Assembly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/internal/runtime/atomic/atomic_amd64.s</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// bool Cas(int32 *val, int32 old, int32 new)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Atomically:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//	if(*val == old){</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//		*val = new;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//		return 1;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//	} else</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//		return 0;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">TEXT ·</span><span class="token function" style="color:#d73a49">Cas</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">SB</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">NOSPLIT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">$</span><span class="token number" style="color:#36acaa">0</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">17</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	MOVQ	ptr</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BX</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	MOVL	old</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">8</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> AX</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	MOVL	</span><span class="token builtin">new</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">12</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> CX</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	LOCK</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	CMPXCHGL	CX</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">BX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	SETEQ	ret</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">16</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	RET</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Explaining this line by line how this maintains atomicity.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">TEXT ·</span><span class="token function" style="color:#d73a49">Cas</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">SB</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">NOSPLIT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">$</span><span class="token number" style="color:#36acaa">0</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">17</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><code>TEXT ·Cas(SB)</code>: Declares the function Cas(CompareAndSwap) in Go assembly.</li>
<li><code>NOSPLIT</code>: Instructs the runtime not to perform stack splitting, ensuring that the function runs without interruption. It tells the Go runtime not to perform stack splitting for that function.</li>
<li><code>$0-17:</code> Specifies the stack frame size for the function (0 bytes for local variables and 17 bytes for arguments/return values).</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">MOVQ ptr</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BX</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Moves the pointer <code>ptr</code> (the address of val) from the function's frame pointer (FP) into the <code>BX</code> register.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">MOVL old</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">8</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> AX</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Moves the old value from the frame pointer into the <code>AX</code> register.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">MOVL </span><span class="token builtin">new</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">12</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> CX</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Moves the new value from the frame pointer into the <code>CX</code> register.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">LOCK</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>This is a crucial instruction. It prefixes the next instruction (CMPXCHGL) with a lock, ensuring that the memory operation is atomic. This lock ensures that no other process or thread can modify the memory location while the compare and exchange instruction is running.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">CMPXCHGL CX</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">BX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>This is the Compare and Exchange instruction. It performs the following:<!-- -->
<ul>
<li>Compares the value in AX (the old value) with the value at the memory location pointed to by BX (the val value).</li>
<li>If the values are equal, it replaces the value at 0(BX) with the value in CX (the new value).</li>
<li>The original value at 0(BX) is loaded into the AX register.</li>
</ul>
</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">SETEQ ret</span><span class="token operator" style="color:#393A34">+</span><span class="token function" style="color:#d73a49">16</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>SETEQ sets the byte at the destination to 1 if the zero flag is set, and to 0 otherwise. In this case, it sets the return value to 1 if the comparison was equal (meaning the swap was successful), and to 0 otherwise.</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">RET</span><span class="token punctuation" style="color:#393A34">:</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Returns from the function</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://prabhavdogra.github.io/prabhav.tech/blog/atomic_operations#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h3>
<p>At the register level, atomicity is achieved because:</p>
<ul>
<li>The LOCK prefix serializes access across CPU cores.</li>
<li>CMPXCHGL ensures all three steps (compare, swap, write-back) happen as one unit.</li>
<li>The CPU guarantees atomicity, eliminating race conditions without software locks.</li>
</ul>
<p>Feel free to be curious and figure out the answers to your questions on your own.</p>]]></content>
        <author>
            <name>Prabhav Dogra</name>
            <uri>https://github.com/prabhavdogra</uri>
        </author>
        <category label="Go" term="Go"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building a Ray Tracer in C++]]></title>
        <id>https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer</id>
        <link href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer"/>
        <updated>2025-02-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This blog is just a quick summary of the book Ray Tracing in One Weekend]]></summary>
        <content type="html"><![CDATA[<p>This blog is just a quick summary of the book <a href="https://raytracing.github.io/books/RayTracingInOneWeekend.htmlRay" target="_blank" rel="noopener noreferrer">Ray Tracing in One Weekend</a></p>
<p>Github Source Code: <a href="https://github.com/dograprabhav/ray_tracer" target="_blank" rel="noopener noreferrer">dograprabhav/ray_tracer</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whatre-we-gonna-make">What're we gonna make?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#whatre-we-gonna-make" class="hash-link" aria-label="Direct link to What're we gonna make?" title="Direct link to What're we gonna make?">​</a></h2>
<p><img decoding="async" loading="lazy" alt="Final" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-2-c18e085804d79caa3e3dc9aca26e4f9c.png" width="1200" height="675" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-1">Milestone 1:<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-1" class="hash-link" aria-label="Direct link to Milestone 1:" title="Direct link to Milestone 1:">​</a></h2>
<p>Before starting anything, in this milestone we just create a sample image. To do that we use one of the simplest formats <strong>P3</strong>. <strong>P3</strong> is a plain text format for <strong>Portable Pixmap (PPM)</strong> image files. It is one of the simplest image formats, where pixel data is represented in plain text.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="p3-image-format">P3 Image Format<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#p3-image-format" class="hash-link" aria-label="Direct link to P3 Image Format" title="Direct link to P3 Image Format">​</a></h3>
<p>In P3, each pixel is defined by three integers corresponding to the red, green, and blue color channels. The first line of the output is "P3", identifying the file format. The second line contains the width and height of the image. The third line specifies the maximum color value (typically 255, representing the maximum intensity for each color channel).
Each subsequent line contains three integers (r, g, b) for each pixel's color in the image.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">Sample P3 image of width 2 pixels and height 3 pixels</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">P3           // Defining format</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">2 3          // Width and Height</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">255          // Maximum color value</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">2 5 15       // (r, g, b) color intensity triplets</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">0 255 255    // (r, g, b) color intensity triplets</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">255 0 255    // (r, g, b) color intensity triplets</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">255 255 0    // (r, g, b) color intensity triplets</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">0 0 0        // (r, g, b) color intensity triplets</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">255 255 255  // (r, g, b) color intensity triplets</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This image looks like: &nbsp; &nbsp; &nbsp; <img decoding="async" loading="lazy" alt="P3" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAA+CAYAAAC/WJKvAAABWWlDQ1BJQ0MgUHJvZmlsZQAAKJFtkE9LAlEUxY//MMpFUbRq4SKIwsLGxLVpVOBisKI/u3HGxkCnxzhS7Vq2aBl9hKhPYEFQHyEIFFq1rEWrQIiS6Tyt1OpdLufH4d7H5QDekCZE0Q+gZDl2dnE+vLG5FQ4+w8cKoQ9eTS+LpKpmOIJv7X2NGjxS76flX7g8ekvvV4KBWm028HTx8ne+5/Ub+bJO/WArurAdwBMlq3uOkHxIHrF5FPlEstnmc8m5Nl+3ZlazKfIdeVAvaAb5kRzJdflmF5eKFf3rBnl9KG+trVBH2WNIYwEZVhgqFCTYCpaY0f87c62dFHYhcAAbOzBRgMPtJB2BIvLkZVjQMYMIWUGUHZdZ/86w41nMOp4k1DueMQFcxYDhSMcb501Dx8DNlNBs7SdZT8Nf3o4pbR6oAoFT131dB4KTQLPuuu9V122eAb4H4LbxCcgTYdJmf7JmAAAAVmVYSWZNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAADkoYABwAAABIAAABEoAIABAAAAAEAAAAtoAMABAAAAAEAAAA+AAAAAEFTQ0lJAAAAU2NyZWVuc2hvdIXQRJcAAAHUaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjYyPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjQ1PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cqlau54AAAGaSURBVGgF7ZqxTsMwFEWd2ApbpwiExC+UMayt4BcY+DsYWPiIlJXO/QPGpBILEhLEIUFycPuMUVK/KJVulzjXz9dXJ69SozrKrrJaHNlHmbx1Pd3sURSZmD9X1YZdv6x3xCneNB0hTPhYaz3FjCRTm9N0Q1zr6baFndzOqWqxG/r07MKuHTw+eXwYvNYsfL25NsMm5W/O7ovYzTaD7du7fTtofL5cDlpnFkWrlRmSa0yUIxAQeqyHBNIg7SGA9vDACToF0kFxesxA2gMn6BRIB8XpMQNpD5ygU+Ql4Enei8VscfAmXzI7yONZfTTrN04PtIcTC4MI0gxQnZYg7cTCIII0A1SnJUg7sTCIIM0A1WkJ0k4sDCJIM0B1WpKXgNvPO1GWpbO4j2j/3dBnnamNdW6G5Ir2IEiYBJBmAktsQZogYRJAmgkssQVpgoRJAGkmsMQWpAkSJgGkmcASW/IS0FakaUoK+wp5/veP+L5e+/UkdFEU+zWTu0dPj/VIVHsUcn45F1VVCevo21j7/79Pc8xUSimSJOlqvwEQpD2eS5b2gwAAAABJRU5ErkJggg==" width="45" height="62" class="img_ev3q"></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-1-results">Milestone 1 Results<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-1-results" class="hash-link" aria-label="Direct link to Milestone 1 Results" title="Direct link to Milestone 1 Results">​</a></h3>
<p>We write a simple loop to render this:</p>
<p><img decoding="async" loading="lazy" alt="P3" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-4-463cf3416dbae775d4b91e4780f4534a.png" width="300" height="300" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-2">Milestone 2:<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-2" class="hash-link" aria-label="Direct link to Milestone 2:" title="Direct link to Milestone 2:">​</a></h2>
<p>In this milestone we setup a basic ray tracing setup.</p>
<ul>
<li>We setup a sphere in the scene.</li>
<li>We setup light rays that detects object in the scene.</li>
<li>On the basis of intersection of light rays and objects in the scene it detects what each pixel in the image should look like.</li>
<li>Set up vector ray header files</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-it-works">How it works?<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#how-it-works" class="hash-link" aria-label="Direct link to How it works?" title="Direct link to How it works?">​</a></h3>
<p><img decoding="async" loading="lazy" alt="How it works?" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-5-cda6bf641c9e71f881dfa2b3ff4ef22c.png" width="1502" height="1212" class="img_ev3q">
This image represents the basic concept of a ray-tracing camera model used in computer graphics and rendering. Let’s break it down step by step:</p>
<ul>
<li>
<p><strong>Camera and Viewport Setup</strong>: The camera center is the origin of the coordinate system. A viewport (camera screen/a plane) is placed in front of the camera at a certain focal length. The viewport is divided into a grid of pixels (X × Y), where each cell represents a pixel in the final rendered image.</p>
</li>
<li>
<p><strong>Ray Tracing Process:</strong> For each pixel in the viewport grid</p>
<ul>
<li>A ray of light is cast from the camera center through the center of the pixel.</li>
<li>The ray travels in the scene and intersects with objects (like the blue sphere in the diagram).</li>
<li>If a ray hits an object, the rendering algorithm calculates the color of that pixel based on:<!-- -->
<ul>
<li>The material properties (color, reflectivity, transparency).</li>
<li>Lighting conditions (shadows, reflections, refractions).</li>
<li>Camera perspective.</li>
</ul>
</li>
<li>The computed color is assigned to the corresponding pixel in the final image.</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="sphere-ray-intersection">Sphere-Ray Intersection<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#sphere-ray-intersection" class="hash-link" aria-label="Direct link to Sphere-Ray Intersection" title="Direct link to Sphere-Ray Intersection">​</a></h3>
<p>This section explains the mathematical derivation for determining the intersection points between a ray and a sphere.</p>
<p><strong>Sphere Equations</strong></p>
<ul>
<li><strong>Sphere centered at (0, 0, 0):</strong>
<ul>
<li><code>x² + y² + z² = r²</code></li>
</ul>
</li>
<li><strong>Sphere centered at (Cx, Cy, Cz):</strong>
<ul>
<li><code>(Cx - x)² + (Cy - y)² + (Cz - z)² = r²</code></li>
</ul>
</li>
</ul>
<p><strong>Vector and Distance</strong></p>
<ul>
<li><strong>Vector from point A(x1, y1, z1) to B(x2, y2, z2):</strong>
<ul>
<li><code>(B - A) = (x2 - x1, y2 - y1, z2 - z1)</code></li>
</ul>
</li>
<li><strong>Distance between points A and B:</strong>
<ul>
<li><code>d = √[(x2 - x1)² + (y2 - y1)² + (z2 - z1)²]</code></li>
</ul>
</li>
<li><strong>Vector from point P(x, y, z) to center C(Cx, Cy, Cz):</strong>
<ul>
<li><code>(C - P) = (Cx - x, Cy - y, Cz - z)</code></li>
</ul>
</li>
</ul>
<p><strong>Point on Sphere Condition</strong></p>
<p>For point P to lie on the sphere, it must be 'r' (radius) distance from the center:</p>
<ul>
<li><code>(C - P) ⋅ (C - P) = (Cx - x)² + (Cy - y)² + (Cz - z)²</code></li>
<li><code>(Cx - x)² + (Cy - y)² + (Cz - z)² = r²</code> (Distance from center)</li>
<li>Therefore: <code>(C - P) ⋅ (C - P) = r²</code></li>
</ul>
<p><strong>Ray Equation</strong></p>
<ul>
<li><strong>General ray equation:</strong> <code>RAY(t) = M * t + N</code>
<ul>
<li><code>M</code> is the ray's direction vector.</li>
<li><code>N</code> is the ray's origin point.</li>
</ul>
</li>
</ul>
<p><strong>Ray-Sphere Intersection</strong></p>
<p>A ray hits the sphere when it's 'r' distance from the center:</p>
<ul>
<li><code>(C - RAY(t)) ⋅ (C - RAY(t)) = r²</code></li>
<li><code>(C - (M * t + N)) ⋅ (C - (M * t + N)) = r²</code></li>
<li>Expanding the equation:<!-- -->
<ul>
<li><code>t² * M ⋅ M - 2 * t * M ⋅ (C - N) + (C - N) ⋅ (C - N) - r² = 0</code></li>
</ul>
</li>
</ul>
<p><strong>Quadratic Formula</strong></p>
<p>Using the quadratic formula (<code>roots = -b ± √(b² - 4ac) / 2a</code>), we get:</p>
<ul>
<li><code>a = M ⋅ M</code></li>
<li><code>b = -2 * M ⋅ (C - N)</code></li>
<li><code>c = (C - N) ⋅ (C - N) - r²</code></li>
</ul>
<p>By solving this quadratic equation for 't', we can find the intersection points (if any) between the ray and the sphere.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-2-results">Milestone 2 Results<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-2-results" class="hash-link" aria-label="Direct link to Milestone 2 Results" title="Direct link to Milestone 2 Results">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Milestone 2 results" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-6-f29e84e0da7e7c516d122e69c21d9ea2.png" width="400" height="225" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-3">Milestone 3:<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-3" class="hash-link" aria-label="Direct link to Milestone 3:" title="Direct link to Milestone 3:">​</a></h2>
<ul>
<li>Scene Abstraction:<!-- -->
<ul>
<li>Introduced a Scene structure to manage all objects, lights, and properties in the environment.</li>
<li>Simplifies the rendering process by treating the scene as a collection of objects instead of handling each separately.</li>
</ul>
</li>
</ul>
<p><strong>Result:</strong> The code is cleaner, modular, and easier to extend in the future (e.g., adding reflections, refractions, and different shapes).</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-3-results">Milestone 3 Results<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-3-results" class="hash-link" aria-label="Direct link to Milestone 3 Results" title="Direct link to Milestone 3 Results">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Milestone 3 results" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-7-b4a5cae6eb6ddedf38cfb98e8085cddf.png" width="400" height="225" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-4">Milestone 4:<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-4" class="hash-link" aria-label="Direct link to Milestone 4:" title="Direct link to Milestone 4:">​</a></h2>
<p><strong>Rendering Improvements</strong></p>
<ul>
<li><strong>Added Anti-Aliasing</strong>
<ul>
<li>Reduced jagged edges in the final image by averaging multiple rays per pixel.</li>
</ul>
</li>
<li><strong>Added Camera Class</strong>
<ul>
<li>Abstracted camera logic for better scene control.</li>
</ul>
</li>
<li><strong>Started Considering Reflected Rays</strong>
<ul>
<li>Introduced initial logic for reflection to create mirror-like surfaces.</li>
<li>Prepares the system for handling realistic light behavior.</li>
</ul>
</li>
</ul>
<p><strong>Material System Enhancements</strong></p>
<ul>
<li><strong>Added Material Class for Diffuse Material</strong>
<ul>
<li>Defined a reusable <code>Material</code> class to manage object properties.</li>
<li>Simplified code structure by encapsulating material behavior.</li>
</ul>
</li>
<li><strong>Added Material Class with Diffuse Material</strong>
<ul>
<li>Implemented Lambertian reflection for diffuse surfaces.</li>
<li>Ensures objects interact naturally with light sources.</li>
</ul>
</li>
<li><strong>Added True Lambertian Reflection</strong>
<ul>
<li>Improved light scattering on rough surfaces.</li>
<li>Used a more accurate random sampling technique for diffuse reflections.</li>
</ul>
</li>
<li><strong>Gamma Correction</strong>
<ul>
<li>Gamma Correction for More Realistic Colors</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="anti-aliasing">Anti-aliasing<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#anti-aliasing" class="hash-link" aria-label="Direct link to Anti-aliasing" title="Direct link to Anti-aliasing">​</a></h3>
<ul>
<li>Reduced jagged edges in the final image by averaging multiple rays per pixel.
<img decoding="async" loading="lazy" alt="Anti-Aliasing" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-8-1d5751270a7f1116e510fe8fe83e5642.png" width="400" height="276" class="img_ev3q"></li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="a-simple-diffuse-material">A Simple Diffuse Material<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#a-simple-diffuse-material" class="hash-link" aria-label="Direct link to A Simple Diffuse Material" title="Direct link to A Simple Diffuse Material">​</a></h3>
<p>A diffuse surface is a surface that scatters light in many directions instead of reflecting it in a single, well-defined direction (like a mirror). This happens because the surface is rough at a microscopic level.</p>
<ul>
<li>Some observations:<!-- -->
<ul>
<li>A light ray that bounces of a diffuse surface has equal probability of bouncing in all directions</li>
<li>They might also be absorbed rather than reflected. The darker the surface, the more likely the ray is absorbed (that’s why it's dark!).</li>
</ul>
</li>
</ul>
<ul>
<li>How we will do it:<!-- -->
<ul>
<li>Generate a random vector inside the unit sphere</li>
<li>Normalize this vector to extend it to the sphere surface</li>
<li>Invert the normalized vector if it falls onto the wrong hemisphere</li>
</ul>
</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Generating randomised reflected rays" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-a23df4ce23087930ddcc9c50d8b81085.png" width="400" height="421" class="img_ev3q"></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="true-lambertian-reflection">True Lambertian Reflection<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#true-lambertian-reflection" class="hash-link" aria-label="Direct link to True Lambertian Reflection" title="Direct link to True Lambertian Reflection">​</a></h3>
<p>A more accurate representation of real diffuse objects is the Lambertian distribution. This distribution scatters reflected rays in a manner that is proportional to cos(𝜙), where 𝜙 is the angle between the reflected ray and the surface normal.</p>
<p>This means that a reflected ray is most likely to scatter in a direction near the surface normal, and less likely to scatter in directions away from the normal.
We do this by</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_Ktv7">src/v4/camera.h</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// rec.normal is the normal to the hemisphere</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    vec3 direction </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> rec</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">normal </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">random_unit_vector</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="gamma-correction">Gamma Correction<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#gamma-correction" class="hash-link" aria-label="Direct link to Gamma Correction" title="Direct link to Gamma Correction">​</a></h3>
<ul>
<li>Gamma Correction for More Realistic Colors<!-- -->
<ul>
<li>Raw pixel values in the renderer are stored in linear color space.</li>
<li>Most displays, however, interpret color values in a non-linear way, requiring gamma correction.</li>
<li>Gamma correction is applied using the equation:</li>
</ul>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">corrected color = raw color ^ (¹⁄ᵧ)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<!-- -->where <strong>γ</strong> (gamma) is typically <strong>2.2</strong>.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="milestone-5">Milestone 5:<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#milestone-5" class="hash-link" aria-label="Direct link to Milestone 5:" title="Direct link to Milestone 5:">​</a></h2>
<p><strong>Metal</strong></p>
<ul>
<li>Add a new class to <strong>Material class</strong> for <strong>Metal object</strong></li>
<li>Modelled light scatter and <strong>reflectance</strong>, enabling realistic surfaces.</li>
<li>Added <strong>mirrored light reflection</strong> for metallic objects.</li>
<li>Implemented <strong>fuzzy reflection</strong>, simulating rough metallic finishes.</li>
</ul>
<p><strong>Dielectrics</strong></p>
<ul>
<li>Explored refraction and how light bends through transparent materials.</li>
<li>Used <strong>Snell’s Law</strong> to determine how rays change direction at surfaces.</li>
<li>Introduced <strong>total internal reflection</strong>, where light stays within the medium.</li>
<li>Implemented the <strong>Schlick Approximation</strong> for <strong>realistic reflection intensity</strong>.</li>
</ul>
<p><strong>Positionable Camera</strong></p>
<ul>
<li>Defines camera viewing geometry for perspective accuracy.</li>
<li>Introduces controls for positioning and orienting the camera, improving scene setup.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="metallic-surfaces-and-reflective-rays">Metallic Surfaces and Reflective Rays<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#metallic-surfaces-and-reflective-rays" class="hash-link" aria-label="Direct link to Metallic Surfaces and Reflective Rays" title="Direct link to Metallic Surfaces and Reflective Rays">​</a></h3>
<p>Introduces metallic materials by modifying how rays bounce off surfaces.
Reflection is modeled using the equation:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">𝑅 = 𝑉 − 2 (𝑉 ⋅ 𝑁) 𝑁 </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" alt="Mirrored reflection" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-9-a2fa0faa5dc050189748bcd884318450.png" width="400" height="306" class="img_ev3q"></p>
<ul>
<li>Where,<!-- -->
<ul>
<li><strong>𝑅</strong> is the reflected ray,</li>
<li><strong>𝑉</strong> is the incoming ray, and</li>
<li><strong>𝑁</strong> is the surface normal.
The reflected ray is traced to determine the color contribution from the metal.</li>
</ul>
</li>
</ul>
<ul>
<li>Fuzziness in Reflection:<!-- -->
<ul>
<li>To simulate rough metal, a fuzziness parameter is introduced.</li>
<li>Instead of perfect reflection, a small random offset is added to the reflected ray direction.</li>
<li>The amount of fuzziness controls how polished or rough the surface appears.</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="dielectrics">Dielectrics<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#dielectrics" class="hash-link" aria-label="Direct link to Dielectrics" title="Direct link to Dielectrics">​</a></h3>
<p>Clear materials such as water, glass, and diamond are dielectrics. When a light ray hits them, it splits into a reflected ray and a refracted (transmitted) ray. We’ll handle that by randomly choosing between reflection and refraction, only generating one scattered ray per interaction.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="snells-law">Snell's Law<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#snells-law" class="hash-link" aria-label="Direct link to Snell's Law" title="Direct link to Snell's Law">​</a></h3>
<p>Where 𝜃 and 𝜃′ are the angles from the normal, and 𝜂 and 𝜂′ are the refractive indices. The geometry is:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">⇒ 𝜂 ⋅ sin𝜃 = 𝜂′ ⋅ sin𝜃′</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>where:</p>
<ul>
<li><strong>𝜂</strong> — Refractive index of the first medium</li>
<li><strong>𝜂′</strong> — Refractive index of the second medium</li>
<li><strong>𝜃</strong> — Incident angle (angle between the incoming ray and the normal)</li>
<li><strong>𝜃′</strong> — Refracted angle (angle between the refracted ray and the normal)</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Snell&amp;#39;s Law" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-1-c90a2fcd331cd757b9f29c65e4ce2722.png" width="421" height="358" class="img_ev3q"></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="total-internal-reflection">Total Internal Reflection<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#total-internal-reflection" class="hash-link" aria-label="Direct link to Total Internal Reflection" title="Direct link to Total Internal Reflection">​</a></h3>
<p>Total Internal Reflection (TIR) occurs when light traveling from a <strong>denser medium</strong> to a <strong>less dense medium</strong> is <strong>completely reflected</strong> rather than refracted. This happens when the <strong>angle of incidence</strong> exceeds the <strong>critical angle</strong>, given by:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">theta = sin⁻¹(n₂ / n₁)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" alt="TIR" src="data:image/png;base64,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" width="300" height="240" class="img_ev3q"></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="schlicks-approximation">Schlick's Approximation<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#schlicks-approximation" class="hash-link" aria-label="Direct link to Schlick's Approximation" title="Direct link to Schlick's Approximation">​</a></h3>
<p>Schlick's Approximation provides an efficient way to estimate <strong>reflectance</strong> at the interface of two materials based on the <strong>angle of incidence</strong>.</p>
<p><img decoding="async" loading="lazy" alt="schlicks" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-12-1ee6d285989f7b6653edf41265cc2396.png" width="1600" height="637" class="img_ev3q"></p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">R₀ = ((n₁ - n₂) / (n₁ + n₂))²</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This approximation avoids expensive computations while providing visually accurate reflections.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="final-render">Final Render<a href="https://prabhavdogra.github.io/prabhav.tech/blog/ray_tracer#final-render" class="hash-link" aria-label="Direct link to Final Render" title="Direct link to Final Render">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Final" src="https://prabhavdogra.github.io/prabhav.tech/assets/images/image-2-c18e085804d79caa3e3dc9aca26e4f9c.png" width="1200" height="675" class="img_ev3q"></p>]]></content>
        <author>
            <name>Prabhav Dogra</name>
            <uri>https://github.com/prabhavdogra</uri>
        </author>
        <category label="C++" term="C++"/>
    </entry>
</feed>