<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Computer, Enhance!]]></title><description><![CDATA[Programming courses, interviews, commentary.]]></description><link>https://www.computerenhance.com</link><image><url>https://substackcdn.com/image/fetch/$s_!7DRL!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4c646b6-92ad-4e9d-95da-e629e19689f4_800x800.png</url><title>Computer, Enhance!</title><link>https://www.computerenhance.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 12 Jun 2026 09:16:07 GMT</lastBuildDate><atom:link href="https://www.computerenhance.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Casey Muratori]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[computerenhance@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[computerenhance@substack.com]]></itunes:email><itunes:name><![CDATA[Casey Muratori]]></itunes:name></itunes:owner><itunes:author><![CDATA[Casey Muratori]]></itunes:author><googleplay:owner><![CDATA[computerenhance@substack.com]]></googleplay:owner><googleplay:email><![CDATA[computerenhance@substack.com]]></googleplay:email><googleplay:author><![CDATA[Casey Muratori]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Q&A #86 (2026-06-10)]]></title><description><![CDATA[Answers to questions from the last Q&A thread.]]></description><link>https://www.computerenhance.com/p/q-and-a-86-2026-06-10</link><guid isPermaLink="false">https://www.computerenhance.com/p/q-and-a-86-2026-06-10</guid><pubDate>Wed, 10 Jun 2026 16:00:39 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/201377389/e275e24d-f0d0-4a43-981f-de8145d8210f/transcoded-261239.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In each Q&amp;A video, I answer questions from the comments on the previous Q&amp;A video, which can be from any part of the course.</em></p><p><em>For those wondering what the name of the audio API was that made me go &#8220;I can&#8217;t believe I am forgetting the acronym&#8221; in the middle of this video, it was <a href="https://en.wikipedia.org/wiki/Audio_Stream_Input/Output">ASIO</a>.</em></p><p>The questions addressed in this video are:</p><ul><li><p><strong>[00:02]</strong> &#8220;The D language actually has this because of Uniform Function Call Syntax. You could have a struct like &#8230; and have the rest of the code be none the wiser (even code like foo.x = 7). I think C# has stuff like this too. Is this what you&#8217;d be hoping for? If so, I&#8217;m surprised - I&#8217;d have guessed you usually don&#8217;t prefer implicit magic like this happening on things that don&#8217;t look like function calls.&#8221;</p></li><li><p><strong>[04:37]</strong> &#8220;Could someone remind me what the &#8216;warm&#8217; criteria was?&#8221;</p></li><li><p><strong>[06:00]</strong> &#8220;I have a question about managing intrusive thoughts while writing code. When thoughts come up about edge cases, performance, reliability, or decisions that may need to be revisited later, how do you decide whether to address them immediately or set them aside? I&#8217;m finding it difficult to iterate quickly because I often get pulled into these concerns before I&#8217;ve built a working v0. I&#8217;ve tried writing TODOs in the code and keeping separate notes, but neither approach has worked well for me.&#8221;</p></li><li><p><strong>[15:47]</strong> &#8220;I now have a question about wasapi (I believe you now use wasapi but if I&#8217;m wrong then you can ignore this question). I&#8217;m writing the sound system for my codebase and had my wav parser ready, mixer chugging along, sat back to enjoy a song but then found out that changing the system volume causes these pops.... I know that changing the volume of a sound wave causes the discontinuity which manifests itself as audio popping but in this case where it&#8217;s not an internal volume I have control over I don&#8217;t know how to fix these. It seems to me as if windows just immediately applied the new volume and my futile attempt of trying to bypass windows&#8217; volume logic didn&#8217;t work since they seem to first clamp my samples and then multiply by the volume... I tried some wasapi gist examples and they all had this same issue. Have you had this problem and fixed it in your own code and could you share your knowledge if you have?&#8221;</p></li><li><p><strong>[25:07]</strong> &#8220;I formed my question about heaps slightly misleading. It wasn&#8217;t about a memory heap, but a data structure, like in the heap sort. In the video together with Primeagen regarding code interviews you commented that heaps are quite slow. So I was wondering, what should you use instead, when the need arises?&#8221;</p></li><li><p><strong>[33:27]</strong> &#8220;I&#8217;m working on a project that uses a cortex-m7, a fairly fast 32-bit embedded core. It has some fancy pipeline features of big boy desktop chips, like a branch predictor, and the ability to dual issue many instructions, but doesn&#8217;t have a RAT (it&#8217;s not &#8220;out-of-order&#8221; at least as far as I know). Do I understand correctly that in CPUs without a RAT, any two adjacent instructions that use the same register are effectively serially dependent? Is this how it used to work in the desktop world back in the day?&#8221;</p></li><li><p><strong>[40:53]</strong> &#8220;This question relates to Part 5: Dependency Chain Stalls and In-order Interleaving. From these results, I would expect 12-way interleaving to maintain peak throughput regardless of chain length (4 FMAs/cycle * 3 cycles = 12 FMAs in flight needed to cover the latency). However, that&#8217;s not what I observe. With 12-way interleaving, throughput decreases from ~3.6 to ~3.0 FMAs/cycle as the chain length grows. I need a minimum of 16-way interleaving for throughput to stay flat at ~3.8 FMAs/cycle. My conclusion is that the CPU can&#8217;t sustain the 3-cycle latency when the FMA execution ports are saturated, resulting in an effective latency of 4 cycles under load. This would explain why I need 4 * 4 = 16 chains to obtain a flat throughput curve. I think you&#8217;ve hinted at this in some of your videos. Would you kindly explain why this happens? Thanks!&#8221;</p></li></ul>
      <p>
          <a href="https://www.computerenhance.com/p/q-and-a-86-2026-06-10">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Intuitive Random Selection (with Marc LeBlanc)]]></title><description><![CDATA[After the ECS interview, Mahk shared a new random selection that's much more intuitive than the one typically used in game development.]]></description><link>https://www.computerenhance.com/p/intuitive-random-selection-with-marc</link><guid isPermaLink="false">https://www.computerenhance.com/p/intuitive-random-selection-with-marc</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Tue, 09 Jun 2026 17:19:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/SL4MzRbNdmk" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-SL4MzRbNdmk" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;SL4MzRbNdmk&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/SL4MzRbNdmk?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Suppose you want to pick a random element from a set that is difficult to iterate. Perhaps the candidate elements are embedded in a spatial hierarchy, and only determined by a complex predicate.</p><p>One obvious way to solve this problem is to first build a &#8220;filtered&#8221; array of all the candidate elements, then pick a random index into that array. This always works, and is fair (assuming the RNG is fair) &#8212; but it requires reserving space for a potentially-large array, and uses up bandwidth and cache space each time a random selection is made.</p><p>A non-obvious-but-common alternative is to use a statistical method where random numbers are chosen during the initial iteration to continuously &#8220;retain or replace&#8221; a running selection. The random numbers must be carefully constructed, and typically require a modulus on each step. Proof of the fairness of the method is not obvious, and requires knowledge of the relevant underlying math.</p><p>In short, while it works, and is likely more efficient than the array method, it has drawbacks.</p><p>Inspired by the way you might write such a query in SQL, Marc &#8220;Mahk&#8221; LeBlanc shared with me a new arrayless picking method that has none of these drawbacks. It&#8217;s very similar to the statistical methods version, but without any of the drawbacks.</p><p>In this video, Mahk presents the algorithm in a series of steps, starting from a &#8220;worst&#8221; random selector, and ending with his new one.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Will AI Make Me Worse?]]></title><description><![CDATA[As people increasingly rely on AI to do some or all of their work, what effects will this have on people's work quality, skills, and emotional state?]]></description><link>https://www.computerenhance.com/p/will-ai-make-me-worse</link><guid isPermaLink="false">https://www.computerenhance.com/p/will-ai-make-me-worse</guid><pubDate>Thu, 04 Jun 2026 19:34:18 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/200639467/82f6e62ca7fe4f0f40754d62b952ac6c.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<div id="youtube2-4fxo6zuhP1c" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;4fxo6zuhP1c&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/4fxo6zuhP1c?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>As people integrate more and more AI into their daily work, will the quality of the work they produce suffer? Will their own skills degrade as a result of relying on AI? Will there be negative psychological effects in the shift from doing work directly to doing it indirectly through AI prompting?</p><p>In this episode, <a href="https://demetrispanos.com/">Demetri</a> and I explore these issues as we consider the broad question many people are asking themselves: &#8220;Will AI make me worse?&#8221;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p><em>As always, the art for the thumbnail, podcast cover, and banner of Wading Through AI were all hand-drawn by <a href="https://x.com/aerettberg">Anna Rettberg</a> in her signature style. We do not currently use generative AI here at <a href="https://mollyrocket.com/">Molly Rocket</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[The First Entity Component System]]></title><description><![CDATA[Marc LeBlanc walks me through how the development of Underworld I & II, System Shock, Flight Unlimited, and finally Thief: The Dark Project gave rise to the architecture we now call an "ECS".]]></description><link>https://www.computerenhance.com/p/the-first-entity-component-system</link><guid isPermaLink="false">https://www.computerenhance.com/p/the-first-entity-component-system</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Mon, 01 Jun 2026 17:31:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/73Do0OScoOU" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-73Do0OScoOU" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;73Do0OScoOU&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/73Do0OScoOU?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>At last year&#8217;s inaugural <em><a href="https://bettersoftwareconference.com/">Better Software Conference</a></em>, I gave a presentation called <em><a href="https://www.youtube.com/watch?v=wo84LFzx5nI">The Big OOPs</a></em>. One of the central figures in the presentation was programmer-designer Marc &#8220;Mahk&#8221; LeBlanc, whom I credited with the key phrase, &#8220;a compile-time hierarchy that matches the domain model&#8221;.</p><p>That quote, and the chronology of <em><a href="https://en.wikipedia.org/wiki/Looking_Glass_Studios">Looking Glass</a></em>&#8217;s entity systems, both came from an extended interview I did with Mahk as part of my research for the talk. At the end of that interview, Mahk and I both had the same thought: &#8220;We should have recorded this!&#8221; There was so much <em>Looking Glass</em> history, nicely focused specifically on the evolution of their entity systems, that it seemed a shame nobody would get to hear it.</p><p>So this year, we did the only logical thing: we both pretended we had never had the conversation, and conducted the whole interview <em>again.</em> This time, we recorded it.</p><p>And here it is! The full two-and-a-half-hour interview, covering everything from Mahk&#8217;s first encounter with <em>Looking Glass<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></em> during <em><a href="https://en.wikipedia.org/wiki/Ultima_Underworld:_The_Stygian_Abyss">Ultima Underworld</a></em>, up through his work on the core engine architecture for <em><a href="https://en.wikipedia.org/wiki/Thief:_The_Dark_Project">Thief: The Dark Project</a></em>.</p><h3>Bonus Unboxing</h3><p>Because we could not find any corroboration posted on the internet, Mahk also unboxed a still-shrink-wrapped, original boxed copy of <em><a href="https://en.wikipedia.org/wiki/Flight_Unlimited">Flight Unlimited</a></em> so we could verify it did, in fact, ship with a batch file that restarted the game to fix C++-induced memory fragmentation:</p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e656e9c-4d31-432d-8f4d-ce3fbc49e20d_492x875.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d54e1db3-eb0b-43ce-ac85-36e28eb71d8b_492x875.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a9f3a27-f28d-401e-b184-8a83a2116d51_492x875.png&quot;}],&quot;caption&quot;:&quot;Mahk's original Flight Unlimited, unboxed for fact-checking!&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb1ed3c8-4adb-4687-ab3a-80b81eafa313_1456x474.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p>After installing the game directly from the original CD, Mahk found the following batch file used to run the game:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;b12c0a60-cc84-45e9-89f6-9e13db6f7f99&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">@echo off
set dos4g=quiet
Y:\cdrom\flight.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
:wacky
if errorlevel 44 goto done
if errorlevel 43 goto refuel
if errorlevel 42 goto credit
goto done
:credit
Y:\cdrom\credits.exe
Y:\cdrom\flight.exe +fromcredits %1 %2 %3 %4 %5 %6 %7 %8 %9
goto wacky
:refuel
Y:\cdrom\flight.exe +refuel %1 %2 %3 %4 %5 %6 %7 %8 %9
goto wacky
:done</code></pre></div><p>To quote Mahk, &#8220;If anything marks this as a genuine <em>LG</em><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> product, it&#8217;s the use of &#8216;wacky&#8217; as a goto label.&#8221;</p><h3>Mahk Links</h3><p>I hope you enjoy the interview! If you&#8217;d like to check out what Mahk&#8217;s been up to since the <em>Looking Glass</em> days, you can find him at the following links:</p><ul><li><p>Mahk&#8217;s YouTube: <a href="https://www.youtube.com/@algorithmancyTube">https://www.youtube.com/@algorithmancyTube</a></p></li><li><p>Mahk&#8217;s Twitch: <a href="https://www.twitch.tv/algorithmancy/videos">https://www.twitch.tv/algorithmancy/videos</a></p></li><li><p>Mahk&#8217;s game design website: <a href="https://8kindsoffun.com">https://8kindsoffun.com</a></p></li></ul><p>Until next time, have fun programming everyone, and I (and Mahk!) will see you on the internet.</p><p style="text-align: right;"><em>&#8212; Casey</em></p><p><em>This is the first in <a href="https://www.computerenhance.com/i/99218768/the-big-oops-paper-trail">a series of Big OOPs supplemental materials</a> that I will be posting over the next several weeks. In addition to this interview with Mahk, there will be paper reviews of each of the major tranches that I used to reconstruct the history presented in the talk. If you&#8217;d like to get those delivered to your inbox when they&#8217;re published, you can take a look at our subscription options here:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Then called <em>Blue Sky</em></p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>&#8220;LG&#8221; here refers to <em>Looking Glass</em>, not the Korean conglomerate <em>LG</em></p></div></div>]]></content:encoded></item><item><title><![CDATA[How to Use uops.info]]></title><description><![CDATA[Now that we've done our own microarchitecture investigations, it's time to get familiar with one of the best x64 microarchitecture data sites.]]></description><link>https://www.computerenhance.com/p/how-to-use-uopsinfo</link><guid isPermaLink="false">https://www.computerenhance.com/p/how-to-use-uopsinfo</guid><pubDate>Sat, 30 May 2026 03:58:08 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/199798918/cdd5dbc2-c1b8-407a-af0f-33318b8bb044/transcoded-224503.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fdNi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fdNi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fdNi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg" width="1456" height="472" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:472,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:357350,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.computerenhance.com/i/199798918?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fdNi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fdNi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F910ab22a-20db-4541-b35d-734a0dbf3329_1920x622.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This is the twelfth video in Part 5 of the Performance-Aware Programming series. Please see the <a href="https://www.computerenhance.com/p/table-of-contents">Table of Contents</a> to quickly navigate through the rest of the course as it is updated, and <a href="https://github.com/cmuratori/computer_enhance">the code repository</a> for downloadable code listings.</em></p>
      <p>
          <a href="https://www.computerenhance.com/p/how-to-use-uopsinfo">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Q&A #85 (2026-05-26)]]></title><description><![CDATA[Answers to questions from the last Q&A thread.]]></description><link>https://www.computerenhance.com/p/q-and-a-85-2026-05-26</link><guid isPermaLink="false">https://www.computerenhance.com/p/q-and-a-85-2026-05-26</guid><pubDate>Wed, 27 May 2026 06:49:39 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/199260802/94d4665c-9e1e-4ba7-9b4c-b3919c3ae13e/transcoded-206587.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In each Q&amp;A video, I answer questions from the comments on the previous Q&amp;A video, which can be from any part of the course.</em></p><p>The questions addressed in this video are:</p><ul><li><p><strong>[0:00:03]</strong> &#8220;I would like to learn/understand more about performance oriented architecture design as most of the performance resources I see are on pinhole omptimizations, do you have specific examples and general guidelines for that?&#8221;</p></li><li><p><strong>[0:05:10]</strong> &#8220;What are the architectural considerations to allow the compiler to SIMDify your code?&#8221;</p></li><li><p><strong>[0:08:13]</strong> &#8220;You once mentioned that heaps are slow in real life. Could you elaborate on why and which algorithms may be used instead in appropriate situations?&#8221;</p></li><li><p><strong>[0:11:09]</strong> &#8220;I saw some advice outside of this course which was to try multiple overlapped reads at once and bypassing the file cache with FILE_FLAG_NO_BUFFERING. Trying this with 32 overlapped reads and reading the whole file into one big buffer (no chunking), I&#8217;m now reading at 6 GB/s. This is in line with my SSD read speed (7GB/s allegedly), but not all the numbers are making sense to me. I have two questions:</p><p>How can bypassing the file cache and reading from SSD possibly be faster than reading from the file cache in memory? My main memory is 64GB so I imagine my whole file fits in the cache.</p><p>Regardless of overlapped reads or bypassing the file cache, if I read the whole file into one big buffer, shouldn&#8217;t I be paying the cost of page faults regardless? I&#8217;d expect page faults and cache inefficiency would limit me to the original 2.5GB/s.&#8221;</p></li><li><p><strong>[0:19:32]</strong> &#8220;With block interleaving, we are doing extra loads/stores, how much more expensive is that in terms of power consumption? does it make sense to do the in order interleaving on some kind of mobile device specifically for battery life or to help maintain higher boost clocks via lower temperatures?&#8221;</p></li><li><p><strong>[0:21:54]</strong> &#8220;At my job we use Unreal and I find myself writing very defensive code. There is so much &#8220;if object exists, do thing, else, log an error and return&#8221; across the code base, it&#8217;s starting to feel like a waste of time. Especially since in a large number of cases, an early return still leaves the game in an unplayable state. The problem isn&#8217;t fixed; only moved elsewhere.</p><p>Do you have any thoughts on when one should do this kind of granular error checking, when one should assert and when it&#8217;s okay to just let it crash?</p><p>Is there a better way or do I just have to keep adding all this noise to my code?&#8221;</p></li><li><p><strong>[0:25:40]</strong> &#8220;Is it fine to expose internals of a struct together with &#8220;helper functions&#8221; to calculate derived data? Should I not worry about exposing internals? Any pointers to where I can learn more about library design in C?&#8221;</p></li><li><p><strong>[0:33:31]</strong> &#8220;In one QA you said that JIT and compile time are not mutually exclusive, but why I never seen some software written in a &#8220;JIT-less&#8221; language and use a JIT library to fill the compile time gap performance?&#8221;</p></li><li><p><strong>[0:36:40]</strong> &#8220;Something that its still not clear to me is: how do I choose a RAM frequency when buying a PC?&#8221;</p></li><li><p><strong>[0:40:09]</strong> &#8220;You said somewhere that you are not a fan o End To End (E2E) tests, why is that?&#8221;</p></li><li><p><strong>[0:45:03]</strong> &#8220;I&#8217;m curious about what to do when a procedure has only one use in the code? How to conciliate this with semantic compression? Assuming that you can only compress something if it was written at least twice. Because sometimes, even though its used once, it makes easier to read.&#8221;</p></li><li><p><strong>[0:47:26]</strong> &#8220;I was wondering: is a relational DB also the 35 year mistake? Since its a statically typed hierarchy that models the domain. My gut feeling is that its not, but it fits very well into the description.&#8221;</p></li><li><p><strong>[0:49:32]</strong> &#8220;In this article the author cites some research papers about how the SOLID principles improve software: https://florian-kraemer.net/software-architecture/2025/02/24/Are-the-SOLID-Principles-problematic.html and related to that, the book <em>Agile software development: Principles, Patterns and Practices</em> by Bob Martin, also tries to give a measurement &#8216;framework&#8217; for SOLID. Any thoughts on this?&#8221;</p></li><li><p><strong>[0:53:53]</strong> &#8220;In OO code is common to use objects with private data and some methods and constructor to keep the internal data always in a valid state, but in a procedural way, like C, you can misuse a struct. How do you deal with this in C or in procedural way in general?&#8221;</p></li><li><p><strong>[0:59:14]</strong> &#8220;Do you think that is worth creating content like the &#8220;OOPs&#8221; talk, &#8220;Clean Code Horrible Performance&#8221;, &#8220;Where does bad software come from?&#8221; (SOLID) where it tries to persuade the viewer that the &#8220;best practice&#8221; he was taught is bad? Because even though you are very sharp in your reasoning, your content still get misinterpreted for several reasons. I was thinking of doing something similar myself, grouping everything I learned from the &#8220;Handmade way&#8221; to present a better way to program, but I&#8217;m not sure if its worth it and I don&#8217;t have decades of experience so I&#8217;m afraid my argumentation would not be good enough.&#8221;</p></li><li><p><strong>[1:05:04]</strong> &#8220;Related to the question above, how do I convince my coworkers that they are doing bad practices?&#8221;</p></li><li><p><strong>[1:06:35]</strong> &#8220;How exactly do I apply WARMED at work?&#8221;</p></li><li><p><strong>[1:08:59]</strong> &#8220;In the end of your IMGUI talk, you said that was excited to see what would be improved in this approach in the next years. So, after 20 years, which improvements you saw?&#8221;</p></li><li><p><strong>[1:11:31]</strong> &#8220;Why compilers don&#8217;t have a #pragma DONT_REMOVE, #pragma END_DONT_REMOVE to make our lives easier instead of writing assembly code to do fake reads and writes for measuring performance for a block of code?&#8221;</p></li><li><p><strong>[1:13:13]</strong> &#8220;I&#8217;m curious on what a web dev handmade hero would look like, because in the game version is possible to ship a commercial game without using any libraries, however I don&#8217;t think that is possible with web, since you need some libraries to deal with security/encryption like HTTPS. So how would you approach this if you were to make a handmade hero for web? Like showing how to create a substack clone, but better :)&#8221;</p></li><li><p><strong>[1:14:59] </strong>&#8220;Knowing the specs of the Lion Cove P-Core of that CPU with 3x load units/ports it makes sense that there is no additional speedup after Read_x3. What puzzles me a bit/makes me curious though is the fact that Read_x3 is consistently the fastest. I tried it numerous times, locked the program to the same single P-core, built dedicated executables to make sure it has nothing to do with some code alignment etc. but Read_x3 is always the fastest with some ~2% edge over Read_x4. Of course 2% is not a huge difference, but I would have assumed that Read_x3 and Read_x4 would converge more or less or if at all that Read_x4 would be slightly faster due to less loop overhead in total.&#8221;</p></li><li><p><strong>[1:19:22]</strong> &#8220;Now that you&#8217;re mainly on Linux, have you been using any of the profiling tools that Linux provides in &lt;linux/perf_event.h&gt; and if you do, what are your thoughts on them?&#8221; / &#8220;In a recent standup I heard how you are now fully switched to Linux and never going back to Windows. I would like to know, what are you now then using for debugging on Linux? As raddbg is not yet ready, though getting closer&#8230;&#8221;</p></li></ul>
      <p>
          <a href="https://www.computerenhance.com/p/q-and-a-85-2026-05-26">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Let's Answer Ray's Question!]]></title><description><![CDATA[Ramon Santamaria asked why one compiler appeared to produce different behavior than others. The underlying technical reason is much more interesting than a simple answer of "undefined behavior".]]></description><link>https://www.computerenhance.com/p/lets-answer-rays-question</link><guid isPermaLink="false">https://www.computerenhance.com/p/lets-answer-rays-question</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Mon, 04 May 2026 18:07:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/zRLnZhhJqpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-zRLnZhhJqpg" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;zRLnZhhJqpg&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/zRLnZhhJqpg?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>A few days ago, Ramon &#8220;Ray&#8221; Santamaria, author of the popular library <a href="https://www.raylib.com/">Raylib</a>, posted <a href="https://x.com/raysan5/status/2049451452997742657">the following code snippet and question</a> on X:</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/raysan5/status/2049451452997742657&quot;,&quot;full_text&quot;:&quot;Why C compilers can't agree in how a standard C library function should works? &#9785;&#65039;\n\nAnd better not to talk about strncpy()... &quot;,&quot;username&quot;:&quot;raysan5&quot;,&quot;name&quot;:&quot;Ray&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1147456686623469568/4SL9jI5P_normal.png&quot;,&quot;date&quot;:&quot;2026-04-29T11:31:18.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HHEcqXybMAAm214.png&quot;,&quot;link_url&quot;:&quot;https://t.co/emqE1q4MVb&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:79,&quot;retweet_count&quot;:22,&quot;like_count&quot;:516,&quot;impression_count&quot;:96142,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;belowTheFold&quot;:false}" data-component-name="Twitter2ToDOM"></div><p>As you can see from the screenshot, GCC and MSVC x64 appear to create binaries that behave &#8220;correctly&#8221; - or at least not obviously wrong - whereas MSVC x86 appears to produce a binary that behaves &#8220;incorrectly&#8221;.</p><p>Although many people replied to Ray&#8217;s post by saying, &#8220;it&#8217;s undefined behavior&#8221; - which is true, because there&#8217;s a missing null terminator - that&#8217;s not a complete answer. That only says why the execution is <em>allowed</em> to be different, not how it actually differs.</p><p>I thought this was a great opportunity to show how we would investigate behavior like this to determine the root cause. I&#8217;ve prepared two videos (and some &#8220;outtakes&#8221; with esoterica) that show this process.</p><p>In this first video, I walk through the entire &#8220;source language&#8221; side of the behavior to show what is actually causing it. I will be posting a second video shortly for people who can read ASM which shows how to go one layer deeper and look at an even more precise answer.</p><p><em>If you&#8217;d like to be emailed when the second video is posted, you can subscribe your email address to either our free or paid tiers using the button below.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Block Interleaving]]></title><description><![CDATA[Breaking up dependency chains to better suit the processor's out-of-order scheduling gets most of the benefit of in-order interleaving without requiring a fully interleaved instruction stream.]]></description><link>https://www.computerenhance.com/p/block-interleaving</link><guid isPermaLink="false">https://www.computerenhance.com/p/block-interleaving</guid><pubDate>Tue, 28 Apr 2026 22:45:56 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/195810514/9101c701-4c74-4b8f-a18d-de21b13ce504/transcoded-44129.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fEGb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fEGb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fEGb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg" width="1456" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:625880,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.computerenhance.com/i/195810514?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fEGb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fEGb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F704fff5b-a28e-4f85-9ea7-c36f478d496f_1920x826.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This is the eleventh video in Part 5 of the Performance-Aware Programming series. Please see the <a href="https://www.computerenhance.com/p/table-of-contents">Table of Contents</a> to quickly navigate through the rest of the course as it is updated, and <a href="https://github.com/cmuratori/computer_enhance">the code repository</a> for downloadable code listings.</em></p>
      <p>
          <a href="https://www.computerenhance.com/p/block-interleaving">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The Ethics of Generative AI]]></title><description><![CDATA[Listen now | What is the appropriate ethical framework for thinking about generative AI?]]></description><link>https://www.computerenhance.com/p/the-ethics-of-generative-ai</link><guid isPermaLink="false">https://www.computerenhance.com/p/the-ethics-of-generative-ai</guid><pubDate>Thu, 23 Apr 2026 16:05:46 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/194373057/df928c7c189c8d054e8d2a2e64758656.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<div id="youtube2-bjO-s4rNPlY" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;bjO-s4rNPlY&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/bjO-s4rNPlY?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>The legal issues surrounding generative AI are something only the court system can decide. The ethical issues, on the other hand, are things that everyone must decide for themselves. Different people with different value systems will come to different conclusions.</p><p>In this episode, <a href="https://demetrispanos.com/">Demetri</a> and I open the can of worms that is &#8220;AI ethics&#8221; and walk through a series of incremental steps people should think through when deciding for themselves if they think generative AI is ethical.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p><em>As always, the art for the thumbnail, podcast cover, and banner of Wading Through AI were all hand-drawn by <a href="https://x.com/aerettberg">Anna Rettberg</a> in her signature style. We do not currently use generative AI here at <a href="https://mollyrocket.com/">Molly Rocket</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Q&A #84 (2026-04-20)]]></title><description><![CDATA[Answers to questions from the last Q&A thread.]]></description><link>https://www.computerenhance.com/p/q-and-a-84-2026-04-20</link><guid isPermaLink="false">https://www.computerenhance.com/p/q-and-a-84-2026-04-20</guid><pubDate>Tue, 21 Apr 2026 02:46:08 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/194840638/9e584af3-4ea6-4c55-ba8d-3951879bbcc0/transcoded-61489.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In each Q&amp;A video, I answer questions from the comments on the previous Q&amp;A video, which can be from any part of the course.</em></p><p>The questions addressed in this video are:</p><ul><li><p><strong>[00:04]</strong> &#8220;Quick question (for Casey or anyone with a suggestion!): I am neither a novice nor an experienced programmer, and would like to learn enough C++ to write some useful code, but I am struggling to find good material.&#8221;</p></li><li><p><strong>[02:18]</strong> &#8220;In the episode &#8216;In-order Interleaving&#8217;, you have a loop that handles multiple elements per loop iteration. When the list of elements isn&#8217;t a multiple of your &#8216;elements per loop&#8217;, we need something after the loop to handle the last few remaining elements. My question is: Is there a particular way to write this &#8216;residual handling&#8217; part? Whenever I&#8217;ve had to do this in my own code it always felt a little awkward.&#8221;</p></li><li><p><strong>[13:25]</strong> &#8220;Hey Casey, what&#8217;s your take on Arm making their own chips now? Sincerely, an Arm engineer.&#8221;</p></li><li><p><strong>[17:05]</strong> &#8220;On the topic of growable arenas, concretely, how do you implement them with respect to the &#8216;layered&#8217; architecture? To grow them, naturally you would need to mmap or VirtualAlloc more memory, but if you&#8217;re far removed from the platform layer and aren&#8217;t writing a program that is frame-based (for example, a compiler) and thus have no opportune time to go back to the platform layer and request more memory, what are your strategies? I can only come up with round-tripping back to the OS using a platform-layer API like &#8216;RequestMoreMemory()&#8217;, or something like this. For more context, this would be for the kind of program that also cannot place upper-bounds on memory usage (again, like in a compiler), but still does not want to be malloc&#8217;ing/free&#8217;ing excessively. I&#8217;m keen to hear how you would approach this problem?&#8221;</p></li><li><p><strong>[26:14]</strong> &#8220;Have you had occasion to use coroutines to write algorithms that must pause/resume? E.g., protocols in networking or software in a hardware simulator.&#8221;</p></li></ul>
      <p>
          <a href="https://www.computerenhance.com/p/q-and-a-84-2026-04-20">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA["Am I Crazy?"]]></title><description><![CDATA[Listen now | Why do people seem to be having such drastically different experiences with AI from one another?]]></description><link>https://www.computerenhance.com/p/am-i-crazy</link><guid isPermaLink="false">https://www.computerenhance.com/p/am-i-crazy</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Thu, 16 Apr 2026 16:05:44 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/194370214/dbf03eabf21a7deb4403ee2883d2e758.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<div id="youtube2-Sp1EmFRDquA" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Sp1EmFRDquA&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Sp1EmFRDquA?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>When it comes to AI, people seem to be having very disparate experiences. Some people become enthusiastic, while others become frustrated, even when apparently attempting similar tasks.</p><p>In this episode of <em>Wading Through AI</em>, <a href="https://demetrispanos.com/">Demetri</a> and I address the root causes of the feeling a lot of people - both pro- and anti-AI - are having that either <em>they</em> must be crazy, or <em>everyone else</em> must be, because their experiences seem to differ so dramatically from what they are hearing from others.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p><em>As always, the art for the thumbnail, podcast cover, and banner of Wading Through AI were all hand-drawn by <a href="https://x.com/aerettberg">Anna Rettberg</a> in her signature style. We do not currently use generative AI here at <a href="https://mollyrocket.com/">Molly Rocket</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[In-order Interleaving]]></title><description><![CDATA[By handing the CPU an instruction stream it can execute in order, we can exceed the limits we hit when we rely on its out-of-order execution capabilities.]]></description><link>https://www.computerenhance.com/p/in-order-interleaving</link><guid isPermaLink="false">https://www.computerenhance.com/p/in-order-interleaving</guid><pubDate>Thu, 16 Apr 2026 03:09:52 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/194365258/709f78f7-1627-4ee5-bf05-c53a76e185a0/transcoded-47060.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CKM1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CKM1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 424w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 848w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CKM1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg" width="1456" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2362184,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.computerenhance.com/i/194365258?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CKM1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 424w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 848w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!CKM1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc63b4f35-7718-4927-85e6-2f53f12fff82_5634x2864.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This is the tenth video in Part 5 of the Performance-Aware Programming series. Please see the <a href="https://www.computerenhance.com/p/table-of-contents">Table of Contents</a> to quickly navigate through the rest of the course as it is updated, and <a href="https://github.com/cmuratori/computer_enhance">the code repository</a> for downloadable code listings.</em></p>
      <p>
          <a href="https://www.computerenhance.com/p/in-order-interleaving">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[My Thoughts on Notch's DLSS Post]]></title><description><![CDATA[The creator of Minecraft recently made a (controversial?) post about DLSS. I wanted to add some relevant context about GPU hardware.]]></description><link>https://www.computerenhance.com/p/my-thoughts-on-notchs-dlss-post</link><guid isPermaLink="false">https://www.computerenhance.com/p/my-thoughts-on-notchs-dlss-post</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Fri, 03 Apr 2026 07:35:09 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/193044322/6404dc04de8b3718f207f10ec0f09064.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>Recently, Minecraft creator Markus &#8220;Notch&#8221; Persson used his popular X account to express a negative opinion of DLSS:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gTQ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gTQ8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 424w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 848w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 1272w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gTQ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png" width="588" height="315" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:315,&quot;width&quot;:588,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27737,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.computerenhance.com/i/193044322?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gTQ8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 424w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 848w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 1272w, https://substackcdn.com/image/fetch/$s_!gTQ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02332bc-3125-43ee-b8a7-48f0df0ed4f0_588x315.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Notch&#8217;s <a href="https://x.com/notch/status/2039561278495068337">post on X</a> about DLSS.</figcaption></figure></div><p>Technically, it was dated April 1st, so it may all have been a ruse! But April Fools joke or not, the vast majority of replies took it seriously.</p><p>While anyone can subjectively agree or disagree with Notch on the value of DLSS, there&#8217;s an underlying objective question regarding his use of the phrase &#8220;<em>THE SAME HARDWARE</em>&#8221;. Many replies took issue with this wording, claiming it was a clear sign Notch did not understand how DLSS worked.</p><p>I&#8217;m not so sure about that.</p><p>I think there is a good case to be made that - given what little NVIDIA tells us - Notch is not objectively wrong about NVIDIA hardware. I didn&#8217;t feel like a contorted X post would be the best way to elaborate on this, so I livestreamed my thoughts on <a href="https://www.twitch.tv/molly_rocket">Twitch</a>, <a href="https://www.youtube.com/mollyrocket">YouTube</a>, and here on Substack.</p><p>The video is included above for those of you that missed the stream.</p>]]></content:encoded></item><item><title><![CDATA[Making Sense of the Hype]]></title><description><![CDATA[Listen now (74 mins) | Using the Anthropic C compiler post as an example, Demetri proposes a two-axis approach for assessing claims about AI.]]></description><link>https://www.computerenhance.com/p/making-sense-of-the-hype</link><guid isPermaLink="false">https://www.computerenhance.com/p/making-sense-of-the-hype</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Fri, 13 Mar 2026 17:14:46 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/190781016/078fefeb331e8140f60a7167645512fe.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<div id="youtube2-HgNKa9UlRF8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;HgNKa9UlRF8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/HgNKa9UlRF8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>In this second episode of <em>Wading Through AI</em>, <a href="https://demetrispanos.com/">Demetri</a> and I discuss the recent <a href="https://www.anthropic.com/engineering/building-c-compiler">Anthropic blog post about &#8220;parallel Claudes&#8221; building a C Compiler</a>, and use it as a case study for how to assess AI announcements.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p><em>As always, the art for the thumbnail, podcast cover, and banner of Wading Through AI were all hand-drawn by <a href="https://x.com/aerettberg">Anna Rettberg</a> in her signature style. We do not currently use generative AI here at <a href="https://mollyrocket.com/">Molly Rocket</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Q&A #83 (2026-03-11)]]></title><description><![CDATA[Answers to questions from the last Q&A thread.]]></description><link>https://www.computerenhance.com/p/q-and-a-83-2026-03-11</link><guid isPermaLink="false">https://www.computerenhance.com/p/q-and-a-83-2026-03-11</guid><pubDate>Thu, 12 Mar 2026 04:19:57 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/190667397/dd549d8f-4ef2-4367-8a4f-573842929d35/transcoded-194421.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In each Q&amp;A video, I answer questions from the comments on the previous Q&amp;A video, which can be from any part of the course.</em></p><p>The questions addressed in this video are:</p><ul><li><p><strong>[0:00:03]</strong> &#8220;Building on using free lists to manage objects with complex lifetimes, how do you handle cases where an object type can vary in size?&#8221;</p></li><li><p><strong>[0:02:33]</strong> &#8220;Can you go into more detail about how to handle IO with queues vs callbacks? A small example on the fancy light-board would be nice.&#8221;</p></li><li><p><strong>[0:07:14]</strong> &#8220;With the recent widespread usage of AI to program in the industry and a fierce push from upper management to enforce usage of AI in development tasks, I am finding myself less and less motivated to program, and also depressed. I have mostly ceased my programming activities outside of working hours.</p><p>Do you have any advice on how to deal with the AI wave and also to continue motivated to program as a hobby and professionally in this environment?&#8221;</p></li><li><p><strong>[0:20:00]</strong> &#8220;Now that you are switching to Linux in full swing have you ported your codebases or what&#8217;s your strategy? I did the opposite thing and fled from Linux because I wanted to start my first big codebase in a more stable environment so it has been the year of the Windows desktop for me which after running a debloat script hasn&#8217;t actually been bad, nevertheless seeing Microsoft&#8217;s behavior does have me yearning for the penguin, and knowing how painful releasing something for Linux is has me wondering if programming against the windows API and using Wine for most of one&#8217;s graphical software is a valid way to proceed.&#8221;</p></li><li><p><strong>[0:29:50]</strong> &#8220;How much of the software you currently write is based on your own thoughts and creativity? I&#8217;ve found myself relying heavily on reading and using open-source projects where similar problems were already solved. After a while, this started to make me feel like an impostor. Do great programmers like yourself write their own code, or do they adapt and build on existing work?&#8221;</p></li><li><p><strong>[0:35:38]</strong> &#8220;This maybe jumping the gun a fair bit. but when you say back of the envelop calculation, does that include the time complexity of whatever algorithm to do correctly?&#8221;</p></li><li><p><strong>[0:39:45]</strong> &#8220;Have you ever written anything in ISPC? From my experience it seems much easier to write than rolling the simd myself, and much more portable.&#8221;</p></li><li><p><strong>[0:42:10]</strong> &#8220;Do you have any recommendations on how to use &#8216;pen &amp; paper&#8217; in the software development process? I&#8217;ve noticed that drawing a problem helps me visualize the problem easier than jumping straight into coding. I&#8217;m working with MIDI and writing a document explaining in my own words how does MIDI encode data helped me in unexpected ways. I&#8217;m wondering if I&#8217;m missing out on any other &#8216;pen &amp; paper&#8217; practice. Any useful tips?&#8221;</p></li><li><p><strong>[0:46:47]</strong> &#8220;Hello I come with another question. How does one go about implementing smooth window resizing with Dangerous Thread Crews? I have the two threads and do get non-blocking resizing but the UI contents of the window jiggle and stretch a bit when resizing (which gets way worse with vsync) and nothing I try (like adding synchronization and using WM_WINDOWPOSCHANGING to allow only one resize per frame) gets rid of the apparent discrepancy between the window size and the size my renderer targets that causes some ugliness. The only reference I have of a program that has smooth resizing and doesn&#8217;t achieve this by updating on each WM_PAINT is your refterm program but I don&#8217;t see any glaring differences between the way you rendered stuff there and it seems like there you just called GetClientRect on each update with no need for anything else... so am I just doing something dumb and missing something or is there some computer wizardry I need to invoke to fix this when programming more complex UIs?&#8221;</p></li><li><p><strong>[0:51:06]</strong> &#8220;In this talk about pathfinding in Age of Empires 2, around the 15-16 minute mark, he mentions turning off SIMD because they were losing floating point precision. I don&#8217;t understand why that was the case for them, can you provide more insight?&#8221;</p></li><li><p><strong>[1:01:33]</strong> &#8220;I&#8217;ve been trying to test how many simultaneous loads can I get with the repetition tester when I do 1, 2, 3 or 4 moves in a loop on the two machines I have access to. My laptop (which has Intel Skylake chip) reports that the memory bandwidth doubles only when I go from 1 to 2 moves per loop, which is expected and reproduces your results from the course. But when I do the same on my desktop (which has Intel Raptor lake chip), the results are the same. The Raptor lake apparently have two type of cores: P-cores and E-cores, where E-cores also have 2 ports capable of executing loads, while P-cores are supposed to be equipped with 3 ports of that type (at least that&#8217;s what I read in Agner Fog manual). To my understanding it means that I should see a bandwidth bump when going from 1 to 2 moves per loop, and when going from 2 to 3 moves per loop. But that doesn&#8217;t happen, I see only one bump (from 1 to 2 moves). I guess that there are some nuances with running the tester on this system that I might not be aware of. But one of them - which is clear to me - is that it is the OS who decides on which core should the tester be run on. So I set the affinity of the tester to CPU1 to make sure that it runs on the P-core. Process Explorer confirmed that it runs on CPU1. But I still could not see the improvement when going from 2 to 3 memory reads. Then I repeated the test with all the cores (one at a time), but I saw no difference in the results.</p><p>It is either my test setup that&#8217;s completely broken, or some other factor that I can&#8217;t see which prevents the bandwidth improvement of a 3 reads loop. I would be grateful if you could give me some pointers here.&#8221;</p></li><li><p><strong>[1:07:25]</strong> &#8220;What are your thoughts about the new dynamicdeopt in msvc that lets you run optimized builds that you can debug with full information because they switch the executable on the fly?&#8221;</p></li><li><p><strong>[1:08:15]</strong> &#8220;I&#8217;d like to ask you about the pass-by-ref vs pass-by-value &#8216;debate&#8217;. Traditional C++ advice is &#8216;always pass by const&amp; anything bigger than 8 bytes&#8217;, but I&#8217;ve recently started seeing some people advocate that 16 byte structs should also be pass-by-value. I know that you couldn&#8217;t care less about const, and you do seem to pass by value small stuff without worrying too much about it in your own code, so .. is there anything I&#8217;m failing to consider here? is this a stupid thing to worry about in the abstract, or is there some general principle that could be useful to keep in mind here?&#8221;</p></li></ul>
      <p>
          <a href="https://www.computerenhance.com/p/q-and-a-83-2026-03-11">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Should You Be A Carpenter?]]></title><description><![CDATA[Listen now (108 mins) | Is entering the "knowledge economy" today too risky given the field's increasing focus on AI?]]></description><link>https://www.computerenhance.com/p/should-you-be-a-carpenter</link><guid isPermaLink="false">https://www.computerenhance.com/p/should-you-be-a-carpenter</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Thu, 05 Mar 2026 21:22:13 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/190033507/29abaac6a753ac63fe0da0f2772487de.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<div id="youtube2-RJyPVLMyyuA" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;RJyPVLMyyuA&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/RJyPVLMyyuA?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>A few weeks ago, I was approached by long time AI-researcher and personal friend <a href="https://demetrispanos.com/">Demetri Spanos</a> about producing a discussion series on emerging AI topics.</p><p>Since Demetri has been working on AI technology for decades, now that it&#8217;s the hot topic, he regularly gets bombarded with questions from friends who want an opinion from the inside. The idea for the series was to see if we could get those answers out to a wider audience.</p><p>As most of you already know, I don&#8217;t work with AI myself, so I&#8217;m really looking forward to these discussions. Demetri is exceptionally good at avoiding hyperbole, and does a fantastic job providing the technical context you need to draw your own conclusions. As you&#8217;ll see, he never tries to sell a specifically positive or specifically negative view of AI, which is very refreshing compared to the normal AI discourse.</p><p>I hope you enjoy this first discussion as much as I did. If you&#8217;re a subscriber, and have questions or topics you&#8217;d like us to cover on future episodes, please feel free to leave a suggestion in the comments! I will be checking regularly to see what our readers are most interested in.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.computerenhance.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.computerenhance.com/subscribe?"><span>Subscribe now</span></a></p><p><em>As always, the art for the thumbnail, podcast cover, and banner of Wading Through AI were all hand-drawn by <a href="https://x.com/aerettberg">Anna Rettberg</a> in her signature style. We do not currently use generative AI at <a href="https://mollyrocket.com/">Molly Rocket</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Dependency Chain Stalls]]></title><description><![CDATA[The CPU's ability to extract parallelism has its limits.]]></description><link>https://www.computerenhance.com/p/dependency-chain-stalls</link><guid isPermaLink="false">https://www.computerenhance.com/p/dependency-chain-stalls</guid><pubDate>Wed, 04 Mar 2026 03:31:39 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/189840675/0e97fb25-8257-4e41-9a4f-67b0d50eadf4/transcoded-77573.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AcnN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AcnN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AcnN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg" width="1456" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:625880,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.computerenhance.com/i/189840675?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AcnN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AcnN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee94ce40-8301-48bb-be91-4060d4336723_1920x826.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This is the ninth video in Part 5 of the Performance-Aware Programming series. Please see the <a href="https://www.computerenhance.com/p/table-of-contents">Table of Contents</a> to quickly navigate through the rest of the course as it is updated, and <a href="https://github.com/cmuratori/computer_enhance">the code repository</a> for downloadable code listings.</em></p>
      <p>
          <a href="https://www.computerenhance.com/p/dependency-chain-stalls">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The Sitdown: Types of DRAM and the DRAM Shortage]]></title><description><![CDATA[On Wednesday mornings, I am often a guest on The Standup podcast. It&#8217;s a wide-audience podcast, so we don&#8217;t go too in-depth on any particular topic. To give myself more time to ramble, I&#8217;ve decided to occasionally do a post-show live stream where I can go into more depth for those interested.]]></description><link>https://www.computerenhance.com/p/the-sitdown-types-of-dram-and-the</link><guid isPermaLink="false">https://www.computerenhance.com/p/the-sitdown-types-of-dram-and-the</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Sat, 31 Jan 2026 02:02:32 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/186369520/74f953a7-8520-4d9b-aa0b-046c55e7649a/transcoded-241067.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On Wednesday mornings, I am often a guest on <a href="https://thestanduppod.com/">The Standup podcast</a>. It&#8217;s a wide-audience podcast, so we don&#8217;t go too in-depth on any particular topic. To give myself more time to ramble, I&#8217;ve decided to occasionally do a post-show live stream where I can go into more depth for those interested.</p><p>This past Wednesday, one of the topics was &#8220;the DRAM shortage&#8221;. I thought it might be nice to go through the different types of DRAM and talk about where they are made, just to give some context to the global supply situation (or lack thereof). I livestreamed it on <a href="https://www.twitch.tv/molly_rocket">Twitch</a>, <a href="https://www.youtube.com/mollyrocket">YouTube</a>, and of course, right here on Substack.</p>
      <p>
          <a href="https://www.computerenhance.com/p/the-sitdown-types-of-dram-and-the">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Q&A #82 (2026-01-27)]]></title><description><![CDATA[Answers to questions from the last Q&A thread.]]></description><link>https://www.computerenhance.com/p/q-and-a-82-2026-01-27</link><guid isPermaLink="false">https://www.computerenhance.com/p/q-and-a-82-2026-01-27</guid><pubDate>Tue, 27 Jan 2026 23:58:15 GMT</pubDate><enclosure url="https://substack-video.s3.amazonaws.com/video_upload/post/186010676/f8099312-2207-4fc3-a203-77f3cc4aaad6/transcoded-03188.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In each Q&amp;A video, I answer questions from the comments on the previous Q&amp;A video, which can be from any part of the course.</em></p><p>The questions addressed in this video are:</p><ul><li><p><strong>[01:02]</strong> &#8220;Could you suggest a resource to learn how to work with large datasets that don&#8217;t fit into VRAM, or even regular RAM?&#8221;</p></li><li><p><strong>[07:24]</strong> &#8220;I do not know how this compares to other approaches, as I&#8217;ve not really tried to optimize my profilers much as it&#8217;s not really my main area of work, but your profiling explanation made me think of a lock-debug profiler I built. It sounds similar to me at least. Do you agree?</p><p>In my solution, each worker thread owns its profiling buffers completely. I keep a thread-local pointer to a block-based buffer that grows in chunks when needed, and all writes are done by the thread with no locks. The only shared step is that when a thread creates its first block, it registers it once by pushing it into a global linked list so the UI can later iterate all threads. To avoid stalling the writers, I double-buffered it. Each thread allocates two buffers and writes into one of them.&#8221;</p></li><li><p><strong>[09:46]</strong> &#8220;About memory usage and the program stack, I believed that this stack could more easily fit in the L1 cache. Isn&#8217;t there a higher risk of cache misses at that level if the data to use has been allocated elsewhere? Would it even be noticeable in terms of performance?&#8221;</p></li><li><p><strong>[14:32]</strong> &#8220;What&#8217;s the best way to multithread a software rasterizer? In my experience, scan line interlacing per triangle was horrific.&#8221;</p></li><li><p><strong>[18:18]</strong> &#8220;Do you know why in the file processing test on the same machine on linux mmaping the file could be outperforming all other methods on medium and large mapped chunk sizes, and on windows the same test was worse than everyone else?&#8221;</p></li><li><p><strong>[21:18]</strong> &#8220;Regarding callbacks, I think I understood the argument about moving things to a queue instead. However, I also can see the benefit of a callback because that&#8217;s synchronous. What if the file IO read some data and stored in a buffer, and the callback now is supposed to handle that read data. If instead you move things to a queue, you&#8217;d have to keep allocating new buffers to keep working on those asynchronous reads, because you don&#8217;t know when the client code will handle those reads. If instead you can very quickly handle this buffer of read data synchronously in the callback, the file IO can reuse the same buffer to store the next chunk.&#8221;</p></li><li><p><strong>[25:45]</strong> &#8220;Can you steelman cases for which an arena/bump allocator (are these the same thing?) is not the preferred way to allocate memory (I imagine it is when lifetimes are not apriori known, but perhaps I am missing more subtlety)? In such cases, what is your preferred method of allocation? Are you forced to go back to new/delete?&#8221;</p></li><li><p><strong>[33:01]</strong> &#8220;Re: Dead Code Elimination Prevention Macros, I&#8217;ve got identical results with `asm volatile (&#8221;&#8220; : &#8220;+v&#8221;(Value));` which tells the compiler that `Value` is both input and output, forcing it to initialize it, as well as preventing from assuming a specific value. It would generate `vpxor` for `0.0` and `vmovaps` for `0.5`. The advantage here is that it&#8217;s quite generic and doe<code>n&#8217;t depend on operand size/type.</code>Could you please elaborate on your choice of explicitly using instructions?&#8221;</p></li><li><p><strong>[35:14]</strong> &#8220;Concerning callbacks, is there a benefit to use callbacks for print-outs/messaging? We have a part of the program that do some calculations which can take time, and it uses callbacks to notify the user about the progress, and waiting to the end of all the computations is not good enough. We also use a callback for a type of mesh calculation that depends on things that this other part of the program shouldn&#8217;t know about. (These things were not my decision, but I guess making the module as isolated as possible makes it easier to use it as a module in another program)&#8221;</p></li><li><p><strong>[37:42]</strong> &#8220;How do you determine if a solution to a problem is more complex than it needs to be? And for inherently complex and interconnected problems, how do you determine if it needs to be subdivided or not? Is there a general approach for working on a complex system with lots of moving parts? (other than me complaining about it :) )&#8221;</p></li></ul>
      <p>
          <a href="https://www.computerenhance.com/p/q-and-a-82-2026-01-27">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[DynamoDB, Don't Leave Me Hanging!]]></title><description><![CDATA[Please put the "root" back into "root cause analysis".]]></description><link>https://www.computerenhance.com/p/dynamodb-dont-leave-me-hanging</link><guid isPermaLink="false">https://www.computerenhance.com/p/dynamodb-dont-leave-me-hanging</guid><dc:creator><![CDATA[Casey Muratori]]></dc:creator><pubDate>Mon, 05 Jan 2026 17:02:02 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/60cb3abd-769b-4211-9cd0-59930c31be68_2784x1856.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A Root Cause Analysis (RCA) post is like the final chapter of a murder mystery: we want to learn &#8220;whodunnit&#8221; and how. Unfortunately, for the large-scale AWS outage in October, the material put out by Amazon ends on more of a cliffhanger.</p><p>To elaborate, in <a href="https://aws.amazon.com/message/101925/">the official RCA</a>, you will see a lengthy explanation of the state that triggers the bug, as well as the cascading series of failures that took down much of AWS. However, the bug itself is described only by the following single sentence:</p><blockquote><p><em>Additionally, because the active plan was deleted, the system was left in an inconsistent state that prevented subsequent plan updates from being applied by any DNS Enactors.</em></p></blockquote><p>That&#8217;s not much to go on.</p><p>Earlier this month, my hopes for a more complete explanation were bolstered by the sudden appearance of <a href="https://www.youtube.com/watch?v=YZUNNzLDWb8">an AWS re:Invent presentation</a> devoted entirely to this particular outage. Sadly, in the hour-long video, only twelve seconds were spent on the actual bug:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;3e1f0133-5335-47ac-85b4-3a5b424596bf&quot;,&quot;duration&quot;:null}"></div><p>Both the RCA and the presentation do a good job of explaining the conditions that triggered the bug. Assuming I understood correctly, the setup goes like this:</p><ol><li><p>DynamoDB uses multiple DNS &#8220;enactors&#8221;, running concurrently, to update DNS records for load balancing (among other things).</p></li><li><p>Enactors use locking and backoff to partially serialize their behavior and make them &#8220;easier to reason about&#8221;<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>.</p></li><li><p>Pathological lock contention can cause one enactor to be &#8220;enacting&#8221; a series of DNS records so old that another enactor will assume they couldn&#8217;t still be in use, and try to delete them.</p></li><li><p>An &#8220;inconsistent state&#8221; occurs when one enactor deletes DNS records it thought were sufficiently old while another enactor updates a DNS endpoint to refer to those same records as authoritative.</p></li><li><p>Enactors will stop operating if they attempt to update a DNS endpoint when it does not already refer to a resolvable name (which it won&#8217;t once the &#8220;inconsistent state&#8221; has occurred).</p></li></ol><p>After all that setup, the story leaves me hanging. To quote the twelve seconds of the presentation:</p><blockquote><p>&#8230; but when that plan&#8217;s missing, our code couldn&#8217;t handle the fact that we tried to point the rollback to nothing &#8230;</p></blockquote><p>To me, this is the <em>actual</em> bug, so I wanted to hear about it in detail. Why didn&#8217;t the code handle that? Or more specifically, why would the code even need to do anything special to &#8220;handle&#8221; that case at all?</p><p>Let me elaborate. Whenever I&#8217;m reading something like an RCA, I&#8217;m building a model of the system in my head. I&#8217;m sure many of you do this as well - it&#8217;s how programmers think through programming problems as they are being described.</p><p>My mental model of the AWS system at this point <em>doesn&#8217;t yet have</em> a bug. If I imagine myself implementing the code they&#8217;re describing here, the pseudo-code version is really just three steps:</p><pre><code><strong>1</strong> get the current value of <em>dynamodb.us-east-1.api.aws</em>
  (<em>"plan-110.ddb.aws"</em> in the presentation example)
<strong>2</strong> set <em>rollback.ddb.aws</em> to the value from step 1
<strong>3</strong> set <em>dynamodb.us-east-1.api.aws</em> to the new value
  (<em>"plan-145.ddb.aws"</em> in the presentation example<em>)</em></code></pre><p>When written in the straightforward way, there should be no issue with step 1 receiving an unresolvable name - some kind of &#8220;null&#8221;, garbage like <code>0.0.0.0</code>, or what I assume would have happened in the actual outage: the &#8220;old&#8221; name whose record had been deleted (shown as <code>plan-110.ddb.aws</code> in <a href="https://youtu.be/YZUNNzLDWb8?t=1562">the example from the re:Invent presentation</a>).</p><p>As far as we&#8217;ve been told, performing these DNS record modifications does not require the enactor to actually communicate with any target load balancers, so it shouldn&#8217;t matter if the target DNS records exist or not. The rollback entrypoint (<code>rollback.ddb.aws</code>) would just be set to the unresolvable name, just as <code>dynamodb.us-east-1.api.aws</code> had an unresolvable name prior to this update. As far as the explanation goes, the enactors shouldn&#8217;t have cared whether these names were resolvable or not.</p><p>Additionally, in step 3, the endpoint (<code>dynamodb.us-east-1.api.aws</code>) would be updated to a valid name. Everything except debug code that looks at <code>rollback.dds.aws</code> would work properly had the enactor continued running. On the <em>next</em> update, literally everything - even <code>rollback.ddb.aws</code> - would be back to normal. It would then point to <code>plan-145.ddb.aws</code>, which remains valid and will exist for some time before being cleaned up.</p><p>So to me, we have not yet hit the root cause! What is it? Something in the way Amazon wrote the enactor code is the <em>actual</em> root cause. I want to know what it is.</p><p>To underscore why I think this is important: taking the explanations at face value, DynamoDB could have been taken down in exactly the same way - causing the same catastrophic outage - simply by <em>manually</em> deleting the target DNS record of a DynamoDB endpoint. According to the available explanation, just that action alone would cause all enactors to cease functioning, and the endpoint would remain an unresolvable name forever.</p><p>So it&#8217;s hard to call any of the &#8220;setup&#8221; the root cause, because none of it is <em>actually required</em> for the exact same outage. An accidental manual deletion of an endpoint&#8217;s target - even just once - would bring the entire system down, and it would be unrecoverable without operator intervention.</p><p>Although the rare, emergent appearance of the &#8220;inconsistent state&#8221; is something that you would want to fix as well, by itself it wouldn&#8217;t have caused AWS to go down catastrophically. At worst it sounds like it would have been a momentary outage. If the enactors weren&#8217;t halted by the inconsistent state, one of them would shortly enact a new DNS plan, and things would be back to normal.</p><p>In closing, I should also mention that my interest in this is more than idle curiosity. A lot of programming paradigms today rely on architectural patterns I consider dangerous for mission-critical systems. As described in the RCA and presentation, this bug sounds like one that wasn&#8217;t really <em>caused</em> by a latent race condition as claimed - it was merely <em>exposed</em> by it. Given the disclosures so far, it sounds far more likely that this bug was <em>actually</em> caused by a bad programming practice in a piece of practical code that communicated with Route53 to change DNS entries.</p><p>So don&#8217;t leave me hanging, DynamoDB! Tell me what the actual code looked like that took down the internet last October. I want to know how something as basic as exchanging a DNS record was written in such a way that it could permanently halt not one but <em>three</em> different concurrent processes on a case as simple as an unresolvable prior record value.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>The presentation did not elaborate on what aspect of DNS &#8220;enacting&#8221;, specifically, the serialization makes easier to reason about.</p></div></div>]]></content:encoded></item></channel></rss>