48 篇关于编译器数值、布局、调度与交付的技术长文。故事常从一个不起眼的问题开始:求个平均值为什么要搬数据,文件明明在为什么找不到,视图没有复制为什么不能释放内存,Debug 正常为什么 Release 失败。
开始阅读
- 想先读一篇有完整排障过程的故事:Debug 一切正常,Release 却把写入操作“优化没了”。
- 正在排查量化结果:乘法没算错,尺度乘错了:整数内核的两张账单 → BatchNorm 变成乘加之后,真正的数值工作才开始 → epsilon 明明不是零,到了整数域却差点失踪。
- 正在处理形状与布局:Reshape 为什么还要写代码:元素没变,搬家路线变了 → 广播不负责喊话:它负责让地址有时前进、有时原地不动 → 第一行正确,第二行失踪:对齐、Stride 与常量填充的连环案。
- 正在追异步执行与资源问题:那只“临时”寄存器,为什么总被别人借走? → 视图没有搬数据,为什么内存仍然不能还? → 等过了事件,为什么还没等到数据?。
- 正在做编译器交付:“我只是重新编译”,为什么安装目录先消失了? → 库文件明明在包里,为什么程序还是说找不到? → 编译器搬了个家,查表模块就失联了 → 同一份发布包,为什么每次哈希都不同?。
- 正在设计后端架构与验证:一条指令的四种身份:代码生成为什么不能只靠字符串 → 汇编看起来对了,机器码也会对吗? → 一份算子文档最有价值的词,可能是“尚未确认”。
数值正确性,从一个整数到一套标尺
| 文章 | 从什么问题展开 |
|---|---|
| 求个平均值,为什么编译器先写起了循环? | 把任意归约轴变成可执行的循环,追踪搬运和布局成本。 |
| 消失的维度:keep_dims=false 为什么能把逆置换弄坏? | 被删掉的轴不再属于原来的坐标系,逆置换必须重建。 |
| 最大值、最小值和求和:长得像三兄弟,不能共用一份数学作业 | 归约框架可以共享,初始化、累加与重定标不能照搬。 |
| 这个归约什么也没做,为什么还不能删? | 数学恒等不代表量化编码恒等,空轴和单位轴也有契约。 |
| 乘法没算错,尺度乘错了:整数内核的两张账单 | 逐项核对输入 scale、输出 scale 与中间乘积的范围。 |
| BatchNorm 变成乘加之后,真正的数值工作才开始 | 从固定统计量到通道乘加,再到乘数、移位和偏置。 |
| 只有几个通道参数,为什么局部内存先满了? | 避免把通道向量铺满整张量,同时守住广播语义。 |
| 写了专用算子,又把它拆掉:一次值得认真记录的设计转向 | 专用仿射算子的引入与撤回,如何比较维护成本与表达力。 |
| epsilon 明明不是零,到了整数域却差点失踪 | 从 epsilon、平方与倒平方根追踪归一化的数值范围。 |
| 浮点全绿、量化全红:一次重写把输出的身份证换成了输入的 | 重写结果类型既描述容器,也携带量化含义。 |
| 太早变聪明的导入器:当代数优化抢在量化信息前面 | 代数变换时机、量化元数据匹配和常量处理为何互相制约。 |
算子与布局,让数学落到真实内存
| 文章 | 从什么问题展开 |
|---|---|
| 分组卷积:切开蛋糕以后,盘子上的标签也得切 | 按组切分输入与权重时,连同量化信息一起维护。 |
| 转置卷积的权重:形状很诚实,内存却说了另一种方言 | 逻辑维度顺序和真实权重存储不同,切片公式就会不同。 |
| Reshape 为什么还要写代码:元素没变,搬家路线变了 | 证明线性元素映射,区分形状变化与布局重排。 |
| 当调试器开始撒谎:一次 Permute,三种 Dump 修法 | 三条分支修法共同揭示观察路径也需要布局契约。 |
| 广播不负责喊话:它负责让地址有时前进、有时原地不动 | 按轴建立地址前进规则,覆盖标量、低秩和复杂广播。 |
| 第一行正确,第二行失踪:对齐、Stride 与常量填充的连环案 | 逻辑宽度、物理步长、对齐补齐与参数表必须一致。 |
| 减去零可以消失,零减去你不行:标量算子的方向感 | 常量折叠、交换律和操作数方向,不能混成一次简化。 |
| Abs 和 Sign:算术只有一行,参数协议却不能复制粘贴 | 一元算子的数学定义,需要贯穿类型、量化和参数编码。 |
| 谁动了我的临时寄存器:让发射器学会借东西、还东西 | 从手写临时寄存器到明确的借用、释放和嵌套约束。 |
| 把激活函数塞进卷积:少一个节点之前,先保住那条量化边界 | 融合卷积与激活之前,保住中间量化与合法形状。 |
| MatMul 后面有个 Sigmoid:为什么编译器偏偏不肯融合 | 多消费者、视图和依赖边界如何限制矩阵乘激活融合。 |
| 权重跑到左边以后:用一个转置恒等式,搬动整个编译链 | 转置恒等式只是起点,权重命名与量化轴还要一起移动。 |
资源与调度,谁还在使用这块数据
| 文章 | 从什么问题展开 |
|---|---|
| 那只“临时”寄存器,为什么总被别人借走? | 用作用域表达寄存器所有权,明确自动归还的边界。 |
| 图里只是多了几个分叉,为什么同步寄存器先耗尽了? | 分叉与依赖汇合如何形成同步资源压力。 |
| 视图没有搬数据,为什么内存仍然不能还? | 跨过视图链追踪异步消费者,防止过早回收底层存储。 |
| 地址能表示,为什么编译器说“内存满了”? | 区分可编码地址范围、分配区间和真实内存预算。 |
| 同一个最终状态,为什么需要两次写出? | 持续状态、最终状态与直接输出,为什么不是同一种缓冲。 |
| 等过了事件,为什么还没等到数据? | 跨执行单元传递状态时,事件必须覆盖真正的数据生产。 |
| catch 住异常之后,半份机器码怎么办? | 错误被捕获之后,已产生的状态与输出仍需明确处理。 |
| 循环只多了一层,为什么二进制快照像换了一个程序? | 循环、标签和独立发射实例如何影响二进制确定性。 |
| “数字已经读出来了”,并不代表输入合法 | 解析成功之后,仍要检查完整消费、符号与字段范围。 |
| 少算一点,为什么反而不敢优化了? | 优化停用也是设计决定:切片、量化与参数尺寸的契约。 |
编译器工程,从开发目录到可交付产物
| 文章 | 从什么问题展开 |
|---|---|
| Debug 一切正常,Release 却把写入操作“优化没了” | 必要写入藏进断言后,关闭检查会改变程序语义。 |
| “我只是重新编译”,为什么安装目录先消失了? | 环境、构建和安装各自负责什么,失败后留下什么。 |
| 头文件是一版,生成器是另一版:编译器构建里的“多人接力” | 头文件、库、生成器和缓存共同决定工具链身份。 |
| 库文件明明在包里,为什么程序还是说找不到? | 真实库、SONAME、链接名与运行搜索路径如何连接。 |
| 编译器搬了个家,查表模块就失联了 | 通过真实功能与缺件测试,验证运行资源能随包移动。 |
| 把一堆编译产物装成一个文件,到底难在哪里? | 模型文件作为协议,必须定义偏移、长度与所有权。 |
| 编译已经失败,目录里为什么还有一个“成功的模型”? | 输出目录、临时产物和旧文件,让成功与失败可判断。 |
| 同一份发布包,为什么每次哈希都不同? | 区分归档事件时间、包内时间和字节可复现性。 |
| 汇编看起来对了,机器码也会对吗? | 伪汇编、汇编、机器码与数学参考各自证明什么。 |
| 一份算子文档最有价值的词,可能是“尚未确认” | 规范要保留未知项,避免把示例表格写成能力承诺。 |
| 搜索到了算子名字,就可以写进“支持列表”吗? | 从存在一个名字到完整编译路径,支持需要多层证据。 |
| 一条指令的四种身份:代码生成为什么不能只靠字符串 | 数学运算、内核、发射与编码的四层职责和错误归属。 |
| 它只是在搬数据,为什么还会算错:张量变换的隐藏契约 | 坐标、步长、别名和量化参数,让搬数据也有语义。 |
| 相同的输出形状,完全不同的答案:池化、缩放与索引归约 | 窗口分母、插值坐标和最大值索引决定具体答案。 |
| 一个函数名,装不下它的数值契约:非线性与归一化的边界 | 定义域、近似、精度与归约轴,比函数名字更重要。 |
按问题串起来读
- 一个改写能不能删除? 恒等归约与重量化 → 重写中的结果类型 → 优化的前提:数学恒等、结果表示和优化前提需要同时成立。
- 看见的错误就是真实错误吗? 调试输出的布局 → 多层回归测试:观察布局与测试基线也可能出错。
- 减少节点是否一定更快? 广播参数与内存 → 卷积与激活融合 → 矩阵乘的融合边界:搬运、内存、舍入边界与消费者关系共同决定收益。
- 一个名字究竟承诺了什么? 算子支持的判定 → 池化与采样语义 → 非线性与归一化:算子名称、输出形状与完整数值语义之间仍有距离。
- 一个文件存在是否等于成功? Release 中的断言副作用 → 模型文件协议 → 命令行的产物约定 → 错误处理的边界:从必要副作用到输出状态,成功要有可验证的条件。
每篇文章均可通过顶部语言菜单切换中英文,通过文末导航继续阅读同辑下一篇。
与博客既有文章衔接
- 构建基础:构建和管理多文件以及编译流程 → 构建阶段的职责、工具链的一致性。
- 装载基础:用户程序的编译、加载及执行流程详解 → 动态库与搜索路径、编译器的可迁移性。
- 内存基础:多程序操作环境中的内存管理与任务切换 → 视图的生存期、地址与容量。
- 调试基础:工程 debug 经验 → 调试输出的布局、Release 中的断言副作用、多层回归测试。
编排日历
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !