ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

15个Verilog文件造出一颗GPU:tiny-gpu极简并行架构拆解

15个Verilog文件造出一颗GPU:tiny-gpu极简并行架构拆解 15个Verilog文件造出一颗GPUtiny-gpu极简并行架构拆解【免费下载链接】tiny-gpuA minimal GPU design in Verilog to learn how GPUs work from the ground up项目地址: https://gitcode.com/GitHub_Trending/ti/tiny-gpu如果你只能给一颗GPU写11条指令你会怎么选tiny-gpu给出了答案——这个极简GPU用不到2000行Verilog把GPU并行计算的骨架完整搭了出来取指、译码、多线程SIMD执行、异步内存访问一个不少图形渲染一概不要。 最小可运行的GPU长什么样tiny-gpu的定位一句话剔除一切图形渲染相关硬件只保留通用计算GPU的核心——并行执行的计算核心、块级线程调度和带带宽控制的内存控制器。仓库分三层结构一目了然硬件实现src/下的12个SystemVerilog模块如 顶层GPU、计算核心、指令译码器、算术逻辑单元、线程调度器、取指单元、装载存储单元内核代码gds/下是烧进程序内存的内核镜像对应矩阵加法和矩阵乘法两个程序仿真测试test/下的Python cocotb脚本负责驱动仿真、校验结果、打印执行轨迹整体架构长这样左侧是GPU顶层控制寄存器、分发器、计算核心、内存控制器右侧是单个计算核心内部核心模块的参数化设计值得看一眼线程数、地址位宽、数据位宽全由参数决定// src/core.sv module core #( parameter DATA_MEM_ADDR_BITS 8, parameter DATA_MEM_DATA_BITS 8, parameter PROGRAM_MEM_ADDR_BITS 8, parameter PROGRAM_MEM_DATA_BITS 16, parameter THREADS_PER_BLOCK 4 ) ( input wire clk, input wire reset, input wire start, output wire done, ... );想改成8线程并行改一个参数的事。 一个线程的一生GPU指令流水线六步拆解现在追踪一条MUL指令在核心里走完全部生命周期的过程。FETCH取指取指单元从程序内存里把PC指向的那条16位指令读出来——相当于拿到一张订单。DECODE译码译码器把指令拆成控制信号目标寄存器是几、源操作数是几、该启用哪条数据通路——相当于看懂订单上点的是什么。REQUEST请求如果是LDR/STR访存指令就向内存控制器发请求——相当于点外卖下单。非访存指令直接跳过这步。WAIT等待等内存应答。真实GPU里这是最耗时的阶段tiny-gpu把它单独做成一个状态整个控制流都围绕这个长延迟来搭。EXECUTE执行ALU按译码结果做加法、乘法、比较——骑手送到了后厨开始做菜。UPDATE更新结果写回本线程的寄存器堆PC加1——上菜开下一单。六步串起来的核心控制流如下图所示你注意看这条流水线上有个巧妙的设计每个线程的寄存器堆里预置了三个只读特殊寄存器——%blockIdx块编号、%blockDim块维度、%threadIdx线程编号。当内核执行MUL R0, %blockIdx, %blockDim再ADD R0, R0, %threadIdx时同一条指令被分裂到4个线程上各用各的%threadIdx算出不同的全局索引各取各的数据——这就是SIMD执行模型的全部硬件秘密。代价是调度器假设所有线程每条指令结束后都收敛回同一个PC后面的扩展章节会讲怎么打破这个假设。 11条指令撑起整个GPU极简ISA设计tiny-gpu的指令集按用途正好分三组。数据搬运LDR、STR负责全局内存读写CONST把立即数装进寄存器。算术运算ADD、SUB、MUL、DIV四则运算CMP比较两个寄存器并把负/零/正结果写进NZP标志位。控制流BRnzp根据NZP标志跳转RET标记线程执行结束外加一个NOP空操作。加上CMP和BRnzp这套组合循环和条件语句都能写出来。x86有数千条指令tiny-gpu只留下能跑矩阵运算的骨架。指令是16位定长高4位操作码低12位操作数字段——4位寄存器编号正好覆盖16个寄存器R0~R12通用后3个是上面说的只读线程寄存器低8位在CONST里复用为立即数。定长的好处很实际decoder.sv 的译码逻辑就是一张case表硬件成本几乎可以忽略。 从零到跑通编译、仿真与第一次矩阵乘法环境三件套iverilogVerilog编译器、cocotbPython测试框架、sv2vSystemVerilog转Verilog。# 安装 Verilog 工具链 brew install icarus-verilog pip3 install cocotb # 下载 sv2v 最新版解压后放进 PATH # 准备构建目录 mkdir build然后只关心两条命令make test_matadd # 矩阵加法8线程各算一个元素 make test_matmul # 矩阵乘法2x2矩阵4线程并行make目标会自动编译整个RTL、转换成Verilog、生成测试平台并运行仿真。跑完后去test/logs看日志开头是初始数据内存中间是逐周期的执行轨迹结尾是最终数据内存。矩阵乘法测试的输入是A [[1,2],[3,4]]、B [[1,2],[3,4]]4个线程一人认领C矩阵的一个元素线程编号算出行列号内层循环做点积。跑对的标准很简单日志末尾从地址8开始的4个字节应当是C [[7, 11], [15, 19]]。日志片段长这样一行就是一个周期内所有线程的指令、PC和寄存器状态⚡ 从玩具到真实tiny-gpu的扩展边界如果fork一份仓库想动手加功能有三个方向值得挑。分支发散当前硬件假设一个块内所有线程每条指令后PC一致所以矩阵乘法内核特意写成所有分支都汇合的样子。想打破它得从 controller.sv 和 scheduler.sv 入手——让调度器管理多个批次warp各自持有PC等它们重新汇合再合并执行。这是真实GPU里最经典的难题之一。共享内存在核心内部给一个块加一片SRAM让块内线程交换中间结果不用反复走全局内存。入口是core.sv再配合 decoder.sv 新增一对片上访问指令。内存合并一批线程经常访问连续地址却各自排队请求。在内存控制器这一层把排队中的相邻请求打包成一次传输能显著提升带宽利用率可以看 lsu.sv 和gpu.sv顶部的控制器接口。三个方向难度递增改ISA加指令最轻decoder.sv一张case表的事动调度策略最重。欢迎挑一个试试。延伸阅读与资源README.md架构、ISA和执行模型的完整说明src/controller.sv核心控制状态机六步流水线的实现处src/scheduler.sv块级线程调度逻辑test/test_matmul.py完整的仿真驱动与结果校验【免费下载链接】tiny-gpuA minimal GPU design in Verilog to learn how GPUs work from the ground up项目地址: https://gitcode.com/GitHub_Trending/ti/tiny-gpu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表