30分钟跑通你的第一块GPU:tiny-gpu保姆级实战
发布时间:2026/9/13 4:13:46 作者:尧图编辑部 阅读量:1,286

30分钟跑通你的第一块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架构文档太厚开源实现又太绕想搞懂GPU在硬件层面怎么工作很难下手。tiny-gpu 是一个用 Verilog 写的极简 GPU仅 15 个源文件、不足 2000 行代码能在你电脑上仿真完整的矩阵运算内核。读完本文你可以亲手跑通矩阵乘法并逐周期看懂它的运行轨迹。路线图看懂原理 → 跑通示例 → 判断结果 → 动手扩展。它到底是什么想学 CPU 怎么工作网上资源一大把GPU 就不一样了——现代 GPU 市场竞争太激烈底层架构细节大多不公开。现成的开源 GPU 项目基本以功能完整为目标看一个文件都要花功夫。tiny-gpu 反着来砍掉所有图形相关部分只保留各类现代加速器GPGPU——用GPU做通用计算而不是画图、ML加速器通用的核心。你可以把它理解成一门GPU 版 CPU 教学课指令集、线程调度、内存控制器一应俱全但体量小到能一口气读完。适合想理解硬件并行、但不打算深入图形学方向的人。一句话定位tiny-gpu 是一颗读得完的教学级 GPU用可运行的最小系统讲清 GPU 原理。15 个 Verilog 文件、不到 2000 行代码全部带注释内置矩阵加法、矩阵乘法两个内核可直接仿真加载程序 → 灌入数据 → 启动内核 → 核对结果全流程自动化有了这张全局图接下来看几个真正驱动它的关键机制。核心原理速览只需理解三件事并行怎么切分、指令长什么样、一条指令怎么走完。Block 与 Thread 的两级并行输入把内核要启动的线程总数写进设备控制寄存器src/dcr.sv过程调度器src/dispatch.sv把线程打包成块 Block一个核心一次只处理一个块块内每个线程各配一套 ALU、LSU、程序计数器和寄存器堆输出块内线程同步执行即 SIMD——同一条指令同时处理各线程自己的数据层级职责对应硬件Block可并行执行的一组线程一个计算核心Thread最小执行单元ALU 寄存器堆 PC妙处在于每个线程的寄存器堆里有 3 个只读寄存器存着 %blockIdx、%blockDim、%threadIdx。同一段代码不同线程算出不同数据——这就是一份代码、多路并行的根源。tiny-gpu 的16位指令集全机只有 11 条指令、每条固定 16 位LDR/STR 读写全局内存ADD/SUB/MUL/DIV 做算术CMP BRnzp 比较后条件跳转循环和 if 就这么写出来的CONST 加载常量RET 表示执行结束。操作数寄存器只占 4 位所以一共 16 个寄存器其中 3 个就是前面说的只读线程标识寄存器。一条指令的六阶段旅程FETCH从程序内存取指令DECODE译码成控制信号REQUESTLDR/STR 时发起内存请求WAIT等内存控制器回数据全流程唯一的异步步骤EXECUTEALU 计算UPDATE结果写回寄存器堆为什么 WAIT 要单列内存带宽有限多核的请求得排队发出线程只能停等。真实 GPU 的许多性能优化正是冲着这段空闲时间去的。原理讲完下一步就是让这颗小 GPU 在你电脑上真正跑起来。30分钟跑通第一个示例给 tiny-gpu 仿真装好环境需要三样东西Icarus Verilog 编译器、cocotb 仿真框架基于 Python 的硬件测试框架、sv2v 转换器把 SystemVerilog 转成 Icarus 能编译的 Verilog。git clone https://gitcode.com/GitHub_Trending/ti/tiny-gpu cd tiny-gpubrew install icarus-verilog pip3 install cocotbLinux 下直接用发行版包管理器装 iverilog 即可sv2v 则去它的开源项目主页下载最新的 release 二进制放进 PATH 里的目录。一条命令运行矩阵乘法mkdir build make test_matmul这行命令背后做的事sv2v 把 src/ 的 SystemVerilog 合并成一份 VerilogIcarus 编译它然后 cocotb 写入内核程序和输入矩阵、启动内核并逐周期打印执行轨迹。看到成片的轨迹日志输出就说明已经跑起来了。结果会落在 test/logs 下的日志文件里下面教你怎么读。看懂运行结果test/logs/ 下的日志按时间戳命名依次包含初始数据内存状态、逐周期执行轨迹、最终数据内存状态末尾一行Completed in N cycles告诉你内核花了几个周期。结果对不对一步核对以 matmul 为例A、B 均为[[1,2],[3,4]]内核启动 4 个线程一线程算一个结果元素。结果元素算式期望值C[0][0]1×1 2×37C[0][1]1×2 2×410C[1][0]3×1 4×315C[1][1]3×2 4×422怎么判断跑成功了打开日志末尾的最终内存显示前 8 字节是输入 A 和 B紧随的 4 字节是结果矩阵——看到 7、10、15、22 依次出现即正确 ✅。测试脚本自带断言失败时终端会直接报Result mismatch at index i并给出期望值和实际值。轨迹怎么读轨迹里每行对应一个周期记录每个核心、每个线程的 PC、正在执行的指令、寄存器值和所处阶段。初读不必逐行挑一个线程跟住它的 PC 一步步前进观察它在 WAIT 阶段停了几拍——那就是原理部分说的等内存。结果会看了再把最容易踩的几个坑提前交代清楚。常见问题与踩坑Qmake 报错sv2v: command not foundA最常见。sv2v 没装或没放进 PATH。终端执行sv2v --version验证仍报错就重新下载二进制放到 PATH 目录如 /usr/local/bin确保任意目录下能直接调用。Qthreads 参数是什么matadd 用 8、matmul 用 4 为什么A它是内核启动的线程总数会写进设备控制寄存器。matadd 逐元素加 8 个数需要 8 个线程matmul 一线程算一个元素2×2 共 4 个。改动它要同步改测试脚本里的数据布局。Q结果在哪日志为什么那么长A日志在 test/logs/重复运行每次生成新文件以最新时间戳为准。先翻到最后的内存显示判断结果错没错错了再用轨迹按 PC 定位异常周期。QLinux 上没有 brew 怎么办Abrew 只是 macOS 的包管理器。Linux 用 apt/yum 装 iverilog、pip3 装 cocotb多出来的只有 sv2v 需要自己下载。坑扫完就可以开始改出属于自己的版本了。下一步去哪儿性能向让它更快指令流水线现在每条指令等上一条彻底结束才取下一条改 src/scheduler.sv 的状态机让下一条在 WAIT 期间就开始取指内存合并相邻线程请求相邻地址时合并成一次事务从 src/lsu.sv 的内存请求路径入手缓存README 里 cache 还是 WIP可以在核心与内存控制器之间加一层 SRAM 省带宽功能向让它更强分支发散当前假设所有线程每条指令后回到同一 PC需让 src/pc.sv 支持线程各自记 PC加新指令在 src/decoder.sv 加操作码到 src/alu.sv 补对应逻辑比如移位共享内存给块内线程加一段可互读的内存src/core.sv 层要开新端口导航收尾完整架构与 ISA 说明见 README.md读源码从 src/core.sv 开始仿真全流程参考 test/test_matmul.py。有扩展想法的话欢迎直接到项目 issue 页面聊作者大概率愿意接话。【免费下载链接】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),仅供参考