跳转至

MASK、CMPMASK、VA 与访存副作用

MASK 的执行宽度

Vector 执行内部使用最多 256 个 lane 位的有效集合。实际 lane 数由元素宽度和操作决定;一个 256 字节向量块通常对应 b8=256、b16/f16=128、b32/f32=64 个 lane。公共 MOVEMASK MASK[0/1], Xn 接口传入两个 64 位 mask word;具体指令会按 dtype 和 mask 模式把它们转换成活动 lane 集合。无效 lane 不执行算术,也不产生目标写回。

MASK 有两种常见来源:

  • 连续 mask/count 模式:前 N 个 lane 有效;末 repeat 若元素数不足,会自动形成低 N 位为 1 的尾掩码。
  • 位图模式:从专用 mask 状态取各 lane 位,再按 block/repeat 截取。

内部尾掩码规则是:非末 repeat 使用该 dtype 的完整 lane 数;末 repeat 使用 total_count % lanes_per_repeat,余数为 0 时仍是全宽。不要把“余数 0”误写成零 lane。

MASK 与 CMPMASK

MASK 控制当前指令哪些 lane 活动;CMPMASK 保存比较结果,供 VSEL、后续比较链或掩码移动使用。二者作用不同:

MOVEMASK MASK[0], X3
MOVEMASK MASK[1], X4
VCMP.EQ.f16 [X0], [X1], X2, MASK
VSEL.f16 [X5], [X6], [X7], X8, MASK

比较只更新活动 lane 对应的结果。被 MASK 关闭的 lane 不应假定 CMPMASK 被清零;若后续需要确定值,先初始化或覆盖完整比较范围。

MASK 是被流水线跟踪的隐式状态。前一条 mask 写尚未完成时,依赖它的 Vector 指令会停顿;"memory" clobber 只能约束编译器,不能消除这种设备侧依赖。

VA

VA<n> 是 Vector Address 状态,不是普通 X 寄存器或 C 指针。gather、scatter、地址合并/拆分和部分 transpose 指令把 VA 中的每-lane 地址或偏移与 Xs 配置共同用于地址生成。

使用规则:

  1. 用该指令族的 builtin 或已接受汇编形式建立 VA,不要用通用 MOV VA0, Xn 猜测接口。
  2. VA 的元素宽度必须与消费指令后缀一致;否则同一位模式会产生不同地址。
  3. MASK 关闭的 lane 不应发出访存请求,但活动 lane 的地址仍需逐 lane 合法。
  4. VA 写入和消费之间存在 RAW 依赖;跨流水线时仍需事件同步。

地址、越界与对齐

标量 LD/ST 的立即数偏移是有符号 12 位,范围 -2048..2047,按字节加入基址。访问宽度由 .b8/.b16/.b32/.b64 决定。汇编器接受字节级偏移不代表运行时地址满足访问宽度;Scalar、Vector、MTE 和缓存/Bank 使用不同层次的对齐规则,详见地址与数据对齐

MTE/Vector/Cube 地址的方括号表示“X 寄存器提供该存储空间地址”,不是通用基址+索引表达式。地址有效性同时取决于:

  • 指针所属 GM/UB/L1/L0A/L0B/L0C 空间;
  • burst、stride、repeat 和 shape 展开的最后一个字节;
  • block 和 bank 对齐;
  • 每个活动 lane 的 gather/scatter 地址;
  • runtime 建立的映射和边界。

没有通用的“越界返回 0”规则。普通越界可能产生错误状态、未定义数据、丢弃写入或设备异常;只有显式带 padding/fill 语义的路径才使用 MOV_PAD_VAL/PADDING 等状态。填充值不把任意非法地址变成安全访问。

访存可见性

  • Scalar load/store 与同一流水线的寄存器依赖由 scoreboard 跟踪。
  • MTE 是异步数据搬运;发射完成不等于目标存储已经可被 Vector/Cube 读取。
  • Vector/Cube 写回与 MTE 搬出之间必须使用匹配的 SET_FLAG/WAIT_FLAG 或屏障序列。
  • 同地址的 RAW/WAR/WAW 不会因为 C 指针相同就自动跨执行域排序。
  • 原子 store 还依赖 ST_ATOMIC_CFG,普通 ST 不继承原子性。

完整的生产者—消费者序列见同步与内存依赖