<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>CUDA on zzudongxiang</title><link>https://www.zzudongxiang.com/tags/cuda/</link><description>Recent content in CUDA on zzudongxiang</description><generator>Hugo</generator><language>zh-cn</language><copyright>2026 zzudongxiang.com · 豫ICP备2022012018号-1 · 豫公网安备41160202000614号</copyright><lastBuildDate>Mon, 01 Apr 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://www.zzudongxiang.com/tags/cuda/index.xml" rel="self" type="application/rss+xml"/><item><title>Nvidia GPU与Huawei NPU</title><link>https://www.zzudongxiang.com/posts/nvidia-gpu-huawei-npu/</link><pubDate>Mon, 01 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.zzudongxiang.com/posts/nvidia-gpu-huawei-npu/</guid><description>&lt;div&gt;
&lt;h1 id="1-nvidia-gpu"&gt;1. Nvidia GPU&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;参考文献：&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: 14.4px"&gt;HeKun-NVIDIA. CUDA-Programming-Guide-in-Chinese&lt;/p&gt;
\[EB/OL\]&lt;p&gt;. &lt;/span&gt;&lt;a href="https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese" rel="noopener noreferrer nofollow" target="_blank"&gt;&lt;span style="font-size: 14.4px"&gt;&lt;a href="https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese"&gt;https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese&lt;/a&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 14.4px"&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Nvidia. Nvidia CUDA编程指南&lt;/p&gt;
\[M\]&lt;p&gt;. 1.1. Nvidia, 2008.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="11-gpu架构"&gt;1.1 GPU架构&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;软件层面架构&lt;/strong&gt;：Nvidia GPU的架构在进行CUDA软件操作时可以抽象为：&lt;code&gt;Thread-&amp;gt;Block-&amp;gt;Grid&lt;/code&gt;三层，通过指定这三个参数可以精确的控制目标运算放在目标的&lt;code&gt;Thread&lt;/code&gt;上进行计算。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;硬件层面架构&lt;/strong&gt;：在硬件层可以讲GPU抽象为：&lt;code&gt;SP(Streaming Processor)-&amp;gt;SM(Streaming Multiprocessor)-&amp;gt;Device&lt;/code&gt;三层，基本对应CUDA软件编程层面的&lt;code&gt;Thread-&amp;gt;Block-&amp;gt;Grid&lt;/code&gt;，Nvidia的GPU在指令集上属于是SIMD（Single Instruction Multiple Data）架构，可以实现单条指令在多个数据的并行处理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;集群层面架构&lt;/strong&gt;：在集群层面，一般按照&lt;code&gt;Host-Device&lt;/code&gt;结构划分，其中一个&lt;code&gt;Host&lt;/code&gt;可以视作一个由CPU、GPU、内存、硬盘等组成的主机，&lt;code&gt;Device&lt;/code&gt;一般特指某一个指定的GPU设备，也就是软件层面的&lt;code&gt;Grid&lt;/code&gt;。&lt;/p&gt;
&lt;img src="images/image-exzl.png" style="display: inline-block;width:65.0%" /&gt;
&lt;p&gt;图. Nvidia的GPU架构&lt;/p&gt;
&lt;h3 id="a-sp--thread"&gt;A. SP / Thread&lt;/h3&gt;
&lt;p&gt;GPU上每个&lt;code&gt;SP&lt;/code&gt;主要由ALU（逻辑控制单元）与FPU（浮点运算单元）组成，可以进行简单的逻辑运算与浮点运算，每个&lt;code&gt;SP&lt;/code&gt;在对应软件层面可以操作的一个&lt;code&gt;Thread&lt;/code&gt;，也是开发者可以操作的最小单元，用户可以借助CUDA在&lt;code&gt;Thread&lt;/code&gt;上实现SPMD（Single Program Multiple Data）操作。&lt;/p&gt;
&lt;h3 id="b-mp--block"&gt;B. MP / Block&lt;/h3&gt;
&lt;p&gt;多个&lt;code&gt;Thread&lt;/code&gt;组成一个&lt;code&gt;Block&lt;/code&gt;，同一个&lt;code&gt;Block&lt;/code&gt;上的&lt;code&gt;Thread&lt;/code&gt;共享同一块内存（Shared Memory），这种方法可以实现同一个&lt;code&gt;Block&lt;/code&gt;上并行的&lt;code&gt;Thread&lt;/code&gt;可以并行的对同一块内存中的数据进行操作。&lt;/p&gt;
&lt;p&gt;在进行CUDA编程时，开发者可以借助一个&lt;code&gt;SM&lt;/code&gt;控制多个&lt;code&gt;Block&lt;/code&gt;中的&lt;code&gt;Thread&lt;/code&gt;进行运算，&lt;code&gt;SM&lt;/code&gt;中还包含一些必要的寄存器、共享内存、L1Cache、Scheduler、SPU、LD/ST单元等。&lt;/p&gt;
&lt;h3 id="c-device--grid"&gt;C. Device / Grid&lt;/h3&gt;
&lt;p&gt;多个&lt;code&gt;Block&lt;/code&gt;一起共同组成一个&lt;code&gt;Grid&lt;/code&gt;，也就是硬件层面与集群层面的&lt;code&gt;Device&lt;/code&gt;，借助该概念可以实现集群中多个GPU之间的数据传输和并行计算。&lt;/p&gt;
&lt;h2 id="12-gpu编程"&gt;1.2 GPU编程&lt;/h2&gt;
&lt;p&gt;Nvidia的GPU上有多个&lt;code&gt;Thread&lt;/code&gt;可以并行的完成矩阵运算，例如在进行通用矩阵乘（GEMM，General matrix multiply）时，不同&lt;code&gt;Thread&lt;/code&gt;在共享内存中取出对应位置的数据进行计算，并讲结果重新放置在共享内存中以实现GEMM的并行计算。&lt;/p&gt;
&lt;img src="images/image-putm.png" style="display: inline-block;width:50.0%" /&gt;
&lt;p&gt;图. 使用共享内存并行计算矩阵乘&lt;/p&gt;
&lt;p&gt;在代码层面的实现过程大致如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Host层面的矩阵乘，假定矩阵的维度是BLOCK_SIZE的整数倍
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MatMul&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Matrix A, &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Matrix B, Matrix C) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 从显存中加载A和B两个矩阵的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#a6e22e"&gt;cudaMalloc&lt;/span&gt;(..., size);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#a6e22e"&gt;cudaMemcpy&lt;/span&gt;(..., ..., size, cudaMemcpyHostToDevice);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 从设备显存中申请储存乘法运算结果的矩阵C
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#a6e22e"&gt;cudaMalloc&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;d_C.elements, size);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 调用内核
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     MatMulKernel&lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;dimGrid, dimBlock&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;(d_A, d_B, d_C); &lt;span style="color:#75715e"&gt;// &amp;lt;&amp;lt;&amp;lt;dimGrid, dimBlock&amp;gt;&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 从显存中获取计算结果C
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#a6e22e"&gt;cudaMemcpy&lt;/span&gt;(..., ..., size, cudaMemcpyDeviceToHost);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 释放显存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#a6e22e"&gt;cudaFree&lt;/span&gt;(...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 调用MatMul()以实现Kernel层的矩阵乘
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; __global__ &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MatMulKernel&lt;/span&gt;(Matrix A, Matrix B, Matrix C) { &lt;span style="color:#75715e"&gt;// __global__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#75715e"&gt;// 每个Thread计算矩阵C中的一个元素，并将结果累加到CValue中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; Cvalue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; row &lt;span style="color:#f92672"&gt;=&lt;/span&gt; blockIdx.y &lt;span style="color:#f92672"&gt;*&lt;/span&gt; blockDim.y &lt;span style="color:#f92672"&gt;+&lt;/span&gt; threadIdx.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; col &lt;span style="color:#f92672"&gt;=&lt;/span&gt; blockIdx.x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; blockDim.x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; threadIdx.x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; e &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; e &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; A.width; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;e)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;         Cvalue &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; A.elements[row &lt;span style="color:#f92672"&gt;*&lt;/span&gt; A.width &lt;span style="color:#f92672"&gt;+&lt;/span&gt; e] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; B.elements[e &lt;span style="color:#f92672"&gt;*&lt;/span&gt; B.width &lt;span style="color:#f92672"&gt;+&lt;/span&gt; col];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;     C.elements[row &lt;span style="color:#f92672"&gt;*&lt;/span&gt; C.width &lt;span style="color:#f92672"&gt;+&lt;/span&gt; col] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Cvalue;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="2-huawei-npu"&gt;2. Huawei NPU&lt;/h1&gt;
&lt;p&gt;Huawei的NPU设备Ascend 910B相较于Nvidia的GPU做了一些有针对性的优化，同时由于NPU主要针对神经网络训练与推理，因此其在芯片设计架构上与Nvidia的GPU拥有完全不同的设计思路。&lt;/p&gt;</description></item></channel></rss>