Buffer 空间设计图解
让读者从整次申请逐层进入一个 bank、一组记录、一条记录和一个字段,每次选择都能回答:这块空间解决什么问题、公式各项为何存在、谁在什么条件下写读、何时清理或复用,以及相对哪个基址访问。
交付结构
交付可离线打开的自包含中文 HTML。桌面端左右等宽、独立滚动;左侧以一个共享空间树驱动的阅读器为中心,右侧解释当前选中对象。
- 左侧保留空间申请流程,明确真正申请、指针传递、切片和释放。流程之后提供参数计算器、可递归树表、当前层真实面积 treemap 和面包屑。左侧不再堆叠互不联动的组织图、公式清单与逐字节窗。
- 树表负责找全对象和保留地址顺序:列出名称、精确大小、占父空间比例、局部区间;展开后进入实际子空间。treemap 负责比较容量,矩形面积严格按当前层字节数分配。选中、展开、进入下一层和返回上层都应有明确操作。
- 右侧说明选中对象:职责、真实源码变量、容量与实际使用口径、公式及当前代入、父子坐标链、相关申请/切片/访问代码。字段、padding、固定预留都可以独立选择并得到自身解释。
- 统一可手算实例贯穿业务动作、token/记录编号、重复份数、地址与总账;至少另有一组代表性大规模预设。计算器变化后整棵树、treemap、右侧公式和源码参数解释一起更新。
不要求保留 1 B 方格、单位方块分页或逐字节窗。需要查看一个字段的字节构成时,递归进入记录即可。不得用彩色导航按钮、只有汇总数的账本、不可继续展开的大块或每块都返回相同代码的交互代替递归分析。
尊重用户指定的源码、语言、输出位置和版本基线。没有要求修改实现时,只生成解释产物,不修算子、不提交、不推送、不发布到外网。
1. 固定源码事实和空间所有权
建模前读取 references/model-contract.md。采用本技能教学样例时再读取 references/elastic-case.md,只复用方法,不把样例当目标算子的事实。
从实际申请入口沿指针传递追到切片、写入、读取、复用与释放:
- 记录源码版本、设备/构建、独立 allocation、owner、地址空间、每 Rank/每进程或共享范围、大小和释放点。
- 记录每个子区的父空间、局部 offset、跨度、元素类型、记录份数、stride、对齐、生命周期和消费者。
- 分清 host hint、容量检查和 Device 地址计算;公开 getter 只能证明地址可取得,不能代替实际消费者证据。
- 标记未找到消费者、未实现阶段、外部定义和未知设备 ABI;缺少状态函数时保留不确定性,不用合理猜测补成源码事实。
- 子区继承父 allocation 的申请证据,但保留自身切片与访问证据;注明“借用切片”,不能暗示每个树节点都有一次 malloc。
当源码包含多组并行核、通信阶段或跨函数生产消费链,或用户明确要求深入/使用子代理时,按相互独立的空间族派发子代理。每个子代理追踪所负责空间的构造、写入、实际消费者、发布条件和回收点,提交公式因子的理由、当前参数实例及逐项行号证据;不能只让子代理改写现有一句话摘要。主代理统一接口、检查空间覆盖和跨分区时序,纠正分支/生命周期冲突后再合入页面。简单buffer可直接分析,不强制无益拆分。
两个 API 指针不一定代表两次申请;别名、放大视图和阶段复用不能重复计账。独立 allocations 分别画框,不暗示它们在物理地址上连续。
2. 建立一棵可递归算清的空间树
选择足够小、能看到复制/去重、未用槽或 padding 的参数。从业务动作依次推导:下一阶段需要的内容 → 记录份数 → 每份字段与类型 → stride/对齐 → 区域终点 → allocation 总容量。
- 以真实包含关系组织树:allocation → 前缀/控制区/各 bank → Rank/核/记录组 → 单条记录 → 字段、对齐填充和保留位。实际存在几层就解释几层,不为画图强造层级。
- 每个父节点的直接子节点按地址顺序无遗漏覆盖父区间。空洞显式建为 padding、reserve 或 unknown;各子节点字节之和严格等于父节点。父节点不再与子节点相加统计。
- 大数组使用可继续进入的重复组和懒生成,组上写明份数、索引范围和精确字节;必须能进入任意代表记录并继续拆字段。不能把全部中间记录永久压成无法解释的一块。
- 区分预留容量、字段最大容量、本轮已知有效记录和实际使用量;未知实际使用量明确写未知。不得从内存跨度推断网络流量。
- 解释真实 AoS、SoA、混合或分块布局,保持同一 token/记录编号。树中的分组应体现字段和重复维度;为便于比较而增加的非物理视图必须注明“不另计空间”。
- 将行内 padding、region 起点对齐、allocator 取整和固定预留分别建模。展示
align_up(n,a)的前后值及差值;没有证据时不把实现选择说成硬件必需。
复杂公式拆成具名中间量,并连接对应子空间或重复维度。右栏逐步显示“符号式 → 当前参数代入 → 带单位结果 → 为什么乘这些份数”。加法数字串不能替代空间结构和原因。
每类空间的正文应围绕该公式形成完整解释,而非只在标题下补一句描述:先说明上下游缺少什么信息以及此buffer为何承担它,再解释每个份数、维度、类型宽度、stride和对齐如何产生;用当前参数的一条记录说明结果,最后沿真实条件列出写入、可见性/发布、读取与清理/复用。区分“协议当前这样实现”“更换布局需同步改哪些访问”和“无法证明绝对必需”,不要把合理设计推论包装为已做过移除实验。
深入到行、单元、字段、padding与固定余量时仍给出该层自己的解释,不能复制整个父空间的文案。重复组说明具体索引范围、当前份数与固定步长的关系;padding解释缺口形成原因及是否被随整块写入;没有找到消费者或清理点就明确写未证实,不能给所有节点套上虚假的“先写后读再清零”。
3. 把源码对象、基址和偏移讲到能核对
节点保存真实代码标识符,右侧以精确 token 匹配高亮,保留下划线、大小写和完整成员名。同一空间的多个真实指针视图应解释角色;说明文字中的教学名称不能伪装成源码变量。
- 为每个节点提供聚焦到自身的代码证据和高亮。例如 payload、元数据、flag 和 padding 分别突出相应变量、地址表达式或对齐常量,而不是只高亮共同父指针。
- 循环处理的不同记录可以引用同一段真实循环,但应显示当前记录的具体索引、代入后的 offset 和被访问字段;说明“同一通用代码作用于不同切片”。没有独立代码对象的 padding 明确注明,并引用造成它的对齐/stride 证据,不虚构变量名。
- 申请、位置计算、实际访问三类证据分开展示。一个字段未找到直接消费者时如实说明;不能给所有子块复制父区访问片段充数。
- 点击空间、公式子项、变量或申请流程时更新右侧,并保持左侧滚动和选择;右栏中的空间链接能定位/选择相关树节点。
跨基址时,在右侧同时画出根 allocation、当前 bank、Tensor/指针视图和目标子空间的坐标关系。每一步标注真实基址名、相对父级的字节偏移、当前数值和局部零点。教学别名显式加注“讲解别名”,并给出它对应的源码表达式。
按表达式递归解释偏移。例如 (A * S + i * C * U) / sizeof(float) 应拆成前一区域的 A * S、第 i 行之前的 i * C * U、行内位置和元素单位转换;各项连接树中实际子空间或维度,解释“跳过什么”和“为什么这样乘”。展示 float 下标与字节 offset 两套坐标,并验证 下标 × sizeof(float) = 字节偏移;不能只摆两条基址公式让读者猜。
4. 单独澄清 bank 的物理空间与逻辑选择
在树中画出源码实际预留的全部 bank。说明 bank 0 和 bank 1 是同一次申请中的两段地址,选择其中一份通常只改变本次指针,不会重新 malloc。
分别列出每类 bank 的基址、单 bank 跨度、选择表达式和 selector 的存放位置;状态 bank 与数据 bank 即使使用同一个选择值,也可能有不同 stride,不能画成一个统一长度的 bank。点击 bank 时,右侧坐标链应显示当前参数下两份地址以及选中的那份。
将“物理预留两份”“本轮选择哪份”“两轮如何复用”分开讲。只有读到完整状态更新与使用顺序后,才把多轮流程称为源码状态机;InitWinState 等定义缺失时,仅提供明确标为假设的选择值演示,不能推断必然交替、下一轮值或读写 epoch。分支和同步确实影响空间生命周期时,在选中对象的解释中补实际流程和证据。
5. 实现递归阅读器和计算器
复用 assets/buffer-design-template.html 的递归阅读结构和纯计算模块,替换目标模型、说明和证据。模板是教学样例,不能原样交付为任意算子的结果。
- 图、树表、面包屑和右侧详情从同一次纯计算结果派生。所有字节、offset、维度使用
BigInt;只在绘制有界矩形比例时转成浮点。 - 使用
children或childrenFactory表达下一层。通过精确索引范围分组控制 DOM 规模;参数再大也不按字节或全部记录创建元素。 - treemap 面积保持真实比例,不给小区增加最小面积。小到无法点击或放下文字的节点仍能在树表找到并进入,展开后以该节点作为新的比较范围。
- 明确说明 treemap 的矩形位置用于排版,不代表地址相邻;地址顺序、半开区间和局部 offset 由树表及右侧坐标图表达。
- 每个参数提供明确的“?”帮助按钮;聚焦输入时在右栏解释含义、单位、真实源码变量、影响空间及限制来源,输入后重算并保留这份解释。窄屏输入聚焦不自动切走,用户显式点击“?”时才进入解释页。
- 把限制分为源码硬约束、容量约束、建模假设和页面输入护栏,逐项说明证据与可调整范围。不能把防止页面计算过大的护栏说成硬件上限,也不能把假设性的 allocation 容量修改说成已经改了 Host/Device。
- 右栏提供“参数与限制 / 容量诊断”入口,参数帮助后附当前输入诊断:显示能计算的公式与代入、失败条件、关联参数及可尝试的模拟调整。非法输入时隐藏旧树、旧图和旧空间推导,清除旧模型引用,但保留右栏并生成本次诊断;解析失败也要显示可改正原因。恢复有效输入后重算并尽可能还原选择和阅读位置。
- 诊断建议按钮只改变本页模拟参数并重新计算,不执行外部代码、不修改 Host 配置或实际申请内存;按钮旁明确说明这一边界。没有完整诊断接口的通用模板降级为元数据帮助和当前错误信息,不展示过期结果。
- 桌面端两栏各占可用宽度 50%,互不带动滚动;窄屏提供“空间 / 解释”切换,保留两个视图 DOM 和原滚动位置。保留键盘操作及明确选中状态,不仅依赖颜色。
- 以文本节点安全显示源码,按精确标识符拆出高亮片段;不执行源码、公式或说明中的字符串,不引入离线不可用依赖。
6. 验证递归关系、代码对应和真实使用
先证明源码映射,再验证模型与浏览器。模型自洽不代表源码正确。
- 用统一小例子独立手算关键容量与地址,另用源码计算、独立脚本或复核验证;覆盖代表性大规模、对齐边界、非法值和超安全整数规模。
- 验证每层子节点连续覆盖父空间、无越界/重叠/遗漏、公式值与本节点字节相等、别名不重复计账。重复组检查首末记录、索引范围和分组总数,懒生成的完整区间证明不能退化成只检查可见节点。
- 验证字段、padding、预留各有独立解释;代码高亮精确对应选中空间。共享通用代码必须显示不同的索引/地址代入,教学别名必须明确标记。
- 验证基址链逐级求和、父局部坐标往返、元素下标与字节单位换算;检查偏移中的每个乘数能追到子区、维度或有证据的常量。
- 验证两份 bank 均存在,选择值不改变物理总量;未知状态行为保持未知,不能用动画替代证据。
- 运行
node <skill目录>/scripts/test_recursive.cjs与node <skill目录>/scripts/test_template.cjs;适配产物运行node <skill目录>/scripts/test_template.cjs <HTML路径>;对模板和适配产物分别运行node <skill目录>/scripts/test_explanations.cjs [HTML路径]检查详细说明与时序证据,并补目标算子的独立数值预期。修改可复用模块后运行同步脚本及--check,避免模板漂移。 - 反例检查必须拒绝子节点缺漏、错误 offset、公式结果被改、错误高亮目标和不守恒分组;真实面积误差只允许绘制舍入,不允许人为放大小空间。
- 在真实浏览器中进入至少三层空间,选择两个不同字段及一个 padding,核对右侧对象、公式、代码高亮和地址链;检查输入聚焦与“?”帮助、限制分层、非法容量后的本次诊断、模拟调整和恢复有效值。验证大规模 DOM 有界、桌面独立滚动、窄屏输入不被自动切走及返回位置。截图应覆盖实际展开的树/treemap 与右侧详情,不能只截标题。
- 验证详细解释覆盖全部不同空间族及代表性子层:必要性、公式因子、当前实例、生产/消费角色、触发条件和复用边界均可追到证据。缺少解释、错用父节点维度、引用不存在的消费者、动态示例仍写旧预设数字都应阻止交付;机械字数检查不能替代对内容和时序的复核。
有浏览器能力时完成视觉与交互验收;不可用时明确尚未做真实浏览器验收。交付 HTML 的可点击路径,简述关键结论、验证范围和源码缺失项;不把页面验证称为设备或网络性能测试。