<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cuda on QSysArch - Quantum Computer System Architecture</title><link>https://qsysarch.com/zh-hk/categories/cuda/</link><description>Recent content in Cuda on QSysArch - Quantum Computer System Architecture</description><generator>Hugo</generator><language>zh-hk</language><lastBuildDate>Sun, 16 Nov 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://qsysarch.com/zh-hk/categories/cuda/index.xml" rel="self" type="application/rss+xml"/><item><title>GPU編譯器架構：CUDA、Triton和DeepSeek</title><link>https://qsysarch.com/zh-hk/posts/cuda-compiler-architecture/</link><pubDate>Sun, 16 Nov 2025 00:00:00 +0000</pubDate><guid>https://qsysarch.com/zh-hk/posts/cuda-compiler-architecture/</guid><description>&lt;p&gt;在為 NVIDIA GPU 編譯程式時，CUDA 通常被視為參考編譯框架。但編譯器究竟是如何運作的呢？編譯器在為 GPU 建立「執行檔」時需要產生哪種指令集架構 (ISA)？編譯器究竟是如何運作的？它使用哪種架構來產生可以從 CPU 啟動並在 GPU 上執行的程式碼？ &#10;&lt;img class="glightbox" src="https://qsysarch.com/images/cuda-q/cuda-logo.webp#right" alt="Cuda Q" style="width: 100%; max-width: 300px;"/&gt;&lt;/p&gt;&#10;&lt;p&gt;這份週日早晨備忘錄旨在對NVIDIA GPU編譯器架構進行高階概述。內容涵蓋GPU指令集、CUDA框架中的NVCC編譯器，以及最終面向GPU指令集的其他架構。&lt;/p&gt;&#10;&lt;h1 id="底層gpu架構"&gt;&#10; 底層GPU架構&#10; &lt;a class="heading-link" href="#%e5%ba%95%e5%b1%a4gpu%e6%9e%b6%e6%a7%8b"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;當針對 GPU 等裝置進行程式設計時，我們需要一套指令集。以 NVIDIA 為例，該裝置是串流多處理器 (SM)，如右圖所示。圖中值得注意的是，它包含許多並發單元，例如 IN32 加法器、特殊功能單元、GEMM+++ 張量核心等，編譯器需要確保以最高效的方式（管線式）使用這些單元（效率定義為最小化空閒時間）。 &#10;&lt;img class="glightbox" src="https://qsysarch.com/images/cuda-q/streaming-multiprocessor.webp#right-500px" alt="串流多處理器架構" /&gt;&lt;/p&gt;&#10;&lt;p&gt;以下是所使用的術語：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ISA（指令集架構）：指令集。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;機器代碼：指令的緊湊二進位表示。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;組合語言：指令的較冗長的文字表示形式&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;NVIDIA GPU 有兩種指令集架構 (ISA)：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;a href="https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html#instruction-set-ref" class="external-link" target="_blank" rel="noopener"&gt;PTX&lt;/a&gt;:並行執行緒執行 - 編譯 Cuda 核心時所使用的中間彙編。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;a href="https://modal.com/gpu-glossary/device-software/streaming-assembler" class="external-link" target="_blank" rel="noopener"&gt;SASS&lt;/a&gt;: Streaming ASSembly（串流彙編）。底層彙編語言，特定於每個 GPU 架構。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;假設我們要編譯這個內核：&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-header"&gt; &lt;span data-label-text="C&amp;#43;&amp;#43;"&gt;&lt;i class="fas fa-code fa-fw small"&gt;&lt;/i&gt;&lt;/span&gt; &lt;button aria-label="copy" data-title-succeed="Copied!"&gt;&lt;i class="far fa-clipboard"&gt;&lt;/i&gt;&lt;/button&gt;&lt;/div&gt;&#10; &#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;__global__&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;normalizeVector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blockIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;blockDim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;threadIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;vx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;vy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;len2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vx&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;vy&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;invLen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rsqrtf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Use SFU fast reciprocal square root&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invLen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Normalized length&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;這裡的神奇之處在於，&lt;code&gt;rsqrtf&lt;/code&gt; 應該被分發到 SFU 管道。它是如何運作的呢？ &lt;code&gt;_float invLen = rsqrtf(len2);_&lt;/code&gt; 這行程式碼會被轉換成 PTX 格式的 &lt;code&gt;rsqrt.approx.ftz.f32&lt;/code&gt;，然後轉換成 SASS 格式的 &lt;code&gt;MUFU.RSQ&lt;/code&gt;，如下圖所示（來自[godbolt](&lt;a href="https://godbolt.org/#g:!%28%28g:!%28%28g:!%28%28h:codeEditor,i:%28filename:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:cuda" class="external-link" target="_blank" rel="noopener"&gt;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:cuda&lt;/a&gt;, selection:(endColumn:2,endLineNumber:15,positionColumn:2,positionLineNumber:15,selectionStartColumn:2,selectionStartL ineNumber:15,startColumn:2,startLineNumber:15),source:&amp;rsquo;&lt;strong&gt;global&lt;/strong&gt;+void+normalizeVector(float*+x,+float*+y,+float*+z,+ int+n)%0A%7B%0A++++int+i+%3D+blockIdx.x+&lt;em&gt;+blockDim.x+%2B+threadIdx.x%3B%0A%0A++++float+vx+%3D+x%5Bi%5D%3B%0A++++float+vx+%3D+x%5Bi%5D%3B%0A++++float +vy+%3D+y%5Bi%5D%3B%0A++++float+len2+%3D+vx&lt;/em&gt;vx+%2B+vy&lt;em&gt;vy%3B%0A%0A++++//+使用+SFU+快速+倒數+平方+根%0A++++flo at+invLen+%3D+rsqrtf(len2)%3B+%0A%0A++++//+標準化+向量%0A++++x%5Bi%5D+%3D+vx+&lt;/em&gt;+invLen%3B%0A++++y%5Bi%5D+%3D+ vy+*+invLen%3B%0A%7D&amp;rsquo;),l:&amp;lsquo;5&amp;rsquo;,n:&amp;lsquo;0&amp;rsquo;,o:&amp;lsquo;CUDA+C%2B%2B+source+%231&amp;rsquo;,t:&amp;lsquo;0&amp;rsquo;)),k:33.333333333333336,l:&amp;lsquo;4&amp;rsquo;,n&amp;rsquo;&amp;rsquo;n,&amp;rsquo;&amp;rsquo;,0:0:&amp;rsquo;,&amp;rsquo;&amp;rsquo;,0:0&amp;rsquo;,&amp;rsquo;n,&amp;rsquo;&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;,0:&amp;rsquo;s 0&amp;rsquo;),(g:!((h:compiler,i:(compiler:nvcc130u2,filters:(b:&amp;lsquo;0&amp;rsquo;,binary:&amp;lsquo;1&amp;rsquo;,binaryObject:&amp;lsquo;1&amp;rsquo;,commentOnly:&amp;lsquo;0&amp;rsquo;,debugCalls:&amp;lsquo;1&amp;rsquo;, demangle:&amp;lsquo;0&amp;rsquo;,directives:&amp;lsquo;0&amp;rsquo;,execute:&amp;lsquo;1&amp;rsquo;,intel:&amp;lsquo;0&amp;rsquo;,libraryCode:&amp;lsquo;0&amp;rsquo;,trim:&amp;lsquo;1&amp;rsquo;,verboseDemangling:&amp;lsquo;0&amp;rsquo;),flagsViewOpen:&amp;lsquo;1&amp;rsquo;,f ontScale:14,fontUsePx:&amp;lsquo;0&amp;rsquo;,j:1,lang:cuda,libs:!(),options:&amp;rsquo;-arch+sm_90+-use_fast_math+-O3&amp;rsquo;,overrides:!(),selection:(en dColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,sta rtColumn:1,startLineNumber:1),source:1),l:&amp;lsquo;5&amp;rsquo;,n:&amp;lsquo;0&amp;rsquo;,o:&amp;rsquo;+NVCC+13.0.2+(Editor+%231)&amp;rsquo;,t:&amp;lsquo;0&amp;rsquo;)),k:33.333333333333336,l:&amp;rsquo; ,n:&amp;lsquo;0&amp;rsquo;,o:&amp;rsquo;&amp;rsquo;,s:0,t:&amp;lsquo;0&amp;rsquo;),(g:!((h:device,i:(compilerName:&amp;lsquo;NVCC+13.0.2&amp;rsquo;,device:&amp;lsquo;SASS+(sm_90)&amp;rsquo;,editorid:1,fontScale:14,fon tUsePx:&amp;lsquo;0&amp;rsquo;,j:1,selection:(endColumn:6,endLineNumber:21,positionColumn:1,positionLineNumber:1,selectionStartColumn:6,s electionStartLineNumber:21,startColumn:1,startLineNumber:1),treeid:0),l:&amp;lsquo;5&amp;rsquo;,n:&amp;lsquo;0&amp;rsquo;,o:&amp;lsquo;Device+Viewer+NVCC+13.0.2+(Edito r+%231,+Compiler+%231)&amp;rsquo;,t:&amp;lsquo;0&amp;rsquo;)),k:33.33333333333333,l:&amp;lsquo;4&amp;rsquo;,n:&amp;lsquo;0&amp;rsquo;,o:&amp;rsquo;&amp;rsquo;,s:0,t:&amp;lsquo;0&amp;rsquo;)),l:&amp;lsquo;2&amp;rsquo;,n:&amp;lsquo;0&amp;rsquo;,0:&amp;rsquo;&amp;rsquo;,&amp;lsquo;&amp;rsquo;t.&lt;/p&gt;</description></item></channel></rss>