Hexagon 编程架构:Q6、HVX 与 HMX

Hexagon 的计算由 Q6 执行程序控制与标量运算,HVX 执行宽向量运算,HMX 执行专用矩阵运算。 本页从指令、寄存器、packet 与 slot 入手,解释硬件线程和向量 context 的区别,再说明 Q6、HVX 和 HMX 怎样使用这些编程对象组织计算。

本页按执行与存储概览展开,以 V79 core 与 HVX 手册为指令模型依据[1][2];HMX 内部操作以公开的 V81 手册辅助解释[3]。页码均指归档 PDF 的页码,V81 的指令编码与精度行为不能直接代替 V79。

1. 执行资源与编程模型:Q6、HVX 与 HMX

1.1.1 Instruction 与寄存器:一条指令表达一次操作

Instruction 是 DSP 指令集中的一个操作,寄存器是它读取或写入的架构状态。 例如 R4 = add(R2, R3) 表达一次 scalar 加法;V4.w = vadd(V1.w, V2.w) 表达一次向量加法,其中 .w 指定按 word 元素解释向量数据。具体指令还规定操作数类型、寻址、predicate、可用 slot 与资源占用[1][2]。

普通 C/C++ 主要描述数据流;编译器选择指令、分配寄存器并组织并行。Intrinsic 可以直接表达特定操作,但最终寄存器与 packet 通常仍由编译器决定。汇编可显式写出架构寄存器和 packet,汇编器负责检查及编码合法组合。

1.1.2 Packet 与 Slot:并行指令的分组与执行位置

Packet 是软件显式组合的一组并行指令。 Hexagon 采用 VLIW(Very Long Instruction Word)模型,编译器/汇编器确定哪些指令放在同一包,以及它们使用哪些 slot;汇编用一对花括号表示 packet。基本模型中每包有 1–4 条指令,单条指令也可构成一个 packet[1]。

一个 packet 固定提供 Slot 0、1、2、3 四个位置。 对普通指令而言,每个 slot 在同一包内接收一条指令;slot 编号约束可以使用的执行通道与资源,不表示四个先后执行时刻。具体取包、解码与发射过程见 §1.2[1][2][3]。

每个 slot 位置固定存放特定 class 的指令。 无论 scalar、vector 还是 matrix 的运算、存储、控制指令,都要按它所属的 class 落到允许的 slot:Core 手册按指令 class 规定 slot 分配,Slot 0/1 主要容纳 LD、ST、ALU32,其中 Slot 0 还可放 MEMOP、NV、System 等;Slot 2/3 主要容纳 XTYPE、ALU32,Slot 2 另有 J、JR,Slot 3 另有 CR[1]。

表 1|Hexagon V79 core 指令 class 与 slot 的对应(整理自手册 Figure 3-2,分组约束见 §4.3[1])

Slot 0 Slot 1 Slot 2 Slot 3
LD、ST、ALU32、MEMOP、NV、System、Some J LD、ST、ALU32、Some J XTYPE、ALU32、J、JR、Some system XTYPE、ALU32、J、CR

表中各 class 的含义[1]:

  • XTYPE:32/64-bit 通用数据运算,包括算术、逻辑、位操作、整数/小数/复数乘法、浮点、permute 与矢量 permute、predicate、shift(可与 add/sub/logical 组合)、矢量 byte/halfword/word 运算。
  • ALU32:32-bit 算术/逻辑运算,含矢量 halfword 运算。
  • LD / ST:8/16/32/64-bit 内存加载/存储;deallocframe / allocframe 也分别归入 LD / ST。
  • MEMOP:针对内存的 8/16/32-bit 操作。
  • NV:new-value 指令,即 new-value 跳转与 new-value 存储。
  • CR:控制寄存器传送、硬件循环设置、predicate 逻辑与归约。
  • J / JR:J 为 PC 相对跳转/调用,JR 为寄存器间接跳转/调用。
  • Some J:J class 中除 call 外、可以放在 Slot 0/1 的部分跳转指令,主要是 compare-jump 与条件跳转,例如 Pd=cmp.xx(); if(Pd.new)jump:hint<target> 和 if(Pd[.new]) jump[:hint] <target> 两种形式。
  • Some system:System class 中可在 Slot 2 出现的子集。System 涵盖 prefetch、cache 操作、bus 操作、load-locked 与 store-conditional;手册未逐条列出能进 Slot 2 的成员,而是以分组约束限定:brkpt/trap/pause/icinva/isync/syncht 是 solo 指令,不得与其它指令同包;memw_locked/memd_locked/l2fetch/trace 必须用 Slot 0,且只能与 ALU32 或(非 FP)XTYPE 同包;dccleana/dcinva/dccleaninva/dczeroa 必须用 Slot 0,Slot 1 须为空或 ALU32。

需要区分的是:这张表按指令 class 划分 slot,而不是把四个 slot 划给 scalar、HVX、HMX 三类引擎。同一个 Slot(如 Slot 0)既可能承载 scalar 的 LD/ST,也可能承载 HVX 的对齐 load/store。HVX 指令另有一套 slot 表,见 §1.2.3;所查 V81 HMX 手册未提供对应表,见 §1.2.4[1][2][3]。

1.1.3 Packet 内的并行:不同 slot 交给不同执行单元

一个 packet 的不同 slot 可以存放交给不同执行单元的指令,它们可以并发执行。 Slot 并不分别归 scalar、HVX、HMX 独占,使用协处理器也不会额外增加四个位置:例如把一个 scalar 加法分配到 Slot 3、一个 HVX 向量加法分配到 Slot 2,前者使用 scalar 资源,后者使用 HVX 资源,另外两个 slot 留空,两条互不依赖的指令即可按同包规则并行发射。四个 slot 给出的是包内普通指令的并行发射位置与数量上限,不直接等于底层 ALU、向量 lane 或矩阵乘法器的数量。包内并行只保证并行发射到不同执行单元,不保证这些指令同时执行结束;能够放进不同 slot,还要满足执行资源不冲突、数据依赖合法——一条指令只能使用其允许的 slot,多条指令占用的计算与访存资源不能超过可用数量,且普通寄存器操作读取的是同包执行前的源值,因此不能把“读取数据 → 使用新数据计算”直接当作两条互不依赖的同包操作(特定新值转发指令另有规则)[1][2][3]。

可以按以下组合理解包内并行:

  • Scalar + Scalar:例如两个互不依赖的普通加法,分配到两个允许的 slot,使用相应 scalar 执行资源[1]。
  • Scalar + HVX:一个标量加法与一个向量加法分别交给 scalar 与 HVX 资源,同包并行发射,前提是二者都满足各自的 slot 与资源约束[1][2]。
  • HVX + HVX:多条向量指令也可同包,但除 slot 外还要检查 HVX 内部资源;例如某些乘法一次占用两个 multiply 资源,不能因为还有空 slot 就再加入需要相同资源的乘法[2]。
  • HMX 操作组包:所查实现将 activation 与 weight 两条 HMX 操作放入同一 packet,具体写法见 §1.2.4[4]。这确认了 HMX 的显式组包形式;它与 scalar/HVX 的混包组合仍需目标架构的指令规则支持,不能仅凭有空 slot 就认定三类计算可任意同时发射[3][4]。

这些组合描述同包的发射与执行关系,不保证包内所有操作都在一个周期内完成;实际完成时间还受指令延迟和访存等待影响[1]。

1.2 指令调度:Q6 如何组织 Scalar、HVX 与 HMX 计算

本节从取指与执行过程展开:Q6 的 instruction sequencer 读取并解码 packet,按指令类别与编码将操作发射到对应资源;scalar、HVX、HMX 各自完成相应计算[1][2][3]。

1.2.1 Hardware thread 与 HVX context:执行状态、绑定与取指

Hardware thread 是处理器能够保持独立程序执行状态、推进一条指令流的硬件执行线程;context 指这条执行路径使用的一组状态。 在这里,scalar hardware thread 有自己的程序位置、R 寄存器等标量执行状态;HVX vector context 则保存向量数据寄存器 V0–V31 与向量谓词寄存器 Q0–Q3 的状态,并提供使用这些状态执行 HVX 指令的能力。二者需要绑定,但它们不是同一个对象[1][2]。

其中,V 寄存器保存参与计算的向量数据,例如一次向量加法的多个输入元素与结果;Q 寄存器保存向量掩码(mask),用一组条件位表示哪些数据位置被选中,供向量选择、条件写出等指令使用。因此,“V/Q 状态”包括向量数据和控制数据选择的掩码两部分[2]。

表 2|软件线程、硬件线程与 HVX vector context 的区别

概念 属于哪一层 保存或执行什么 数量应怎样理解
Software thread 操作系统或运行时调度的软件执行单元 程序任务及其软件执行状态 多个软件线程可以分时使用硬件线程,数量不等于硬件线程数
Scalar hardware thread Hexagon 处理器的硬件执行线程 保持自身的 PC、R 寄存器等状态,按 packet 推进指令流 Scalar 支持多硬件线程;具体数量取决于实现
HVX vector context 供 hardware thread 绑定的向量执行状态 向量数据寄存器 V0–V31、向量谓词(掩码)寄存器 Q0–Q3,以及使用这些状态执行 HVX 指令的能力 数量可少于 scalar hardware thread 数,不能当成额外增加的一组线程

图 1 按“选择线程 → 按 PC 取包 → 解码与发射 → 执行并更新状态”展示 Hexagon 的执行过程。 本项目归档的 V79 Compute DSP 配置上限为 8 个 hardware thread,HVX 容量为 6 个 context;图中据此展开 8 个 hardware thread,每个线程分别持有一个 PC(Program Counter,程序计数器寄存器),用于指示该线程要执行的 instruction packet。8 是 hardware thread 上限,6 是向量 context 容量,二者分别计数v79-cdsp-capacity。

Q6 hardware thread、取指与 Scalar/HVX/HMX 指令发射关系

图 1|Hardware thread 的执行状态与指令发射关系(根据手册自绘[1][2][3])。上方每个 thread 分别持有 PC,L1 I Cache 与 instruction sequencer 之间区分取指地址请求和 instruction packet 返回;下方展开 scalar 寄存器、控制状态、slot 与执行资源,右侧展开一个 HVX context 的寄存器及 HMX 的 FP16 数据流。框与箭头表达逻辑关系,不表示已核对的物理布线或完整流水线。

结合图 1,可以沿着以下过程理解程序如何执行:

  1. 选择线程并取包。 线程调度与取指硬件选择可推进的 hardware thread,instruction sequencer(IS)按该线程的 PC 发起取指,从 L1 Instruction Cache(L1I)取得 packet;若指令缓存未命中,则需要等待下层存储提供指令[1]。
  2. 解码并发射。 IS 解码 packet 中的指令,按已编码的 slot 分配与指令类别,将操作发射到相应执行资源:scalar 算术交给 X unit,普通 scalar 访存交给 LD/ST,HVX 指令交给向量资源,HMX 指令交给矩阵资源。指令编码与类别确定要执行什么操作,Slot 0–3 约束操作可以从哪些位置发射;同一 packet 可以包含合法组合的不同类别指令,具体规则见 §1.1、§1.2.3 与 §1.2.4[1][2][3]。
  3. 使用该线程的状态执行。 Scalar 指令使用该线程的 R 寄存器与控制状态;HVX 指令使用它所绑定 context 的 V/Q 寄存器;HMX 指令使用相应的矩阵操作数与累加状态。图中 R 寄存器只展开一套类别,实际各线程分别保持自己的 scalar 状态;HVX 的“×6”表示图示 context 数,一个线程执行 HVX 指令需要绑定可用的 context[1][2][3]。
  4. 完成 packet 并推进程序。 按 V79 core 手册第 17 页的架构定义,PC 在当前 packet 完成时更新,按顺序执行、分支或硬件循环的结果指向后续 packet。执行结果写入相应状态,后续指令按规定的数据依赖继续执行[1]。

同一线程必须等当前 packet 完成后才能执行下一个吗? 架构上,当前 packet 完成后才更新可见 PC;但这条规定没有要求取指、解码、发射与执行各阶段都停止重叠,也没有把 PC 定义为线程向 IS 报告 ready 的信号。后续 packet 能否发射,还取决于操作数是否可用、所需资源能否接收新操作等条件。V79 core 手册第 10 页明确由硬件处理流水线冲突,因此不能仅凭 PC 的更新规则推断同一线程的具体发射间隔[1]。

并行度来自哪两个层次? 第一层是 packet 内的指令并行:编译器/汇编器把满足 slot、资源和数据依赖约束的指令放进同一 packet,硬件将它们并行发射到相应执行单元,例如合法组合的 scalar 加法与 HVX 向量加法。第二层是 hardware thread 之间的并行:不同线程分别保存 PC 与寄存器状态,硬件可以交错推进它们的 packet,使不同线程的工作在流水线与执行资源允许时重叠;一个线程等待数据时,其他就绪线程可以提供可执行的工作。线程数不直接等于同周期发射的 packet 数[1][2]。

多个线程如何避免资源冲突,IS 发射后能否继续发射? 包内资源冲突首先由合法组包规则约束;跨线程竞争则由硬件调度与资源可用性检查处理。寄存器状态分别保存,解决的是线程之间的状态隔离;执行单元和访存接口仍可能被多个线程共同使用。只要后续 packet 满足依赖与资源条件,IS 就可以继续发射,已经发出的操作由执行流水线推进;若所需资源忙、操作数未就绪或缓存未命中,相关工作就需要等待。因此,“发射后继续推进”有条件,并不保证始终无阻塞;具体线程选择策略与跨线程发射宽度需以目标实现为准[1][2]。

1.2.2 Scalar 计算:取出 packet,使用标量执行资源

Q6 是 Hexagon DSP 常见的工程称呼;概览图中的 Q6 Scalar Core 特指其标量执行部分。 它有 instruction sequencer、通用寄存器、控制状态和执行单元,能够完成普通程序中的取指、地址计算、算术、循环与分支[1]。Q6 sequencer 取出某个 hardware thread 的 packet 后,将其中的标量算术交给 X unit 等 scalar 资源,普通 Load/Store 交给 LD/ST;指令使用该线程的 R 寄存器和控制状态。图中的一组 R0–R31 表示寄存器类别,没有逐线程展开[1][2]。

表 3|Q6 Scalar Core 的主要组成与职责

组成 结构与功能 在计算中的作用
Instruction sequencer 读取和处理指令 packet 按 packet 推进程序,依照编码确定的 slot 发射指令
General registers 32 个 32-bit 寄存器 R0–R31,可组成对齐的 64-bit 寄存器对 保存地址、尺寸、标量操作数与结果
X units 两个,图中标为 S2/S3;支持 ALU、FP、64-bit shift、MAC、branch 整数与浮点运算、移位、乘加及程序流操作
Load/store units 两个,图中标为 S0/S1;各有 Load/Store 功能,也支持部分 32-bit ALU 指令 内存与通用寄存器之间的数据访问
Control state PC/USR、P0–P3、循环与寻址寄存器等 记录程序位置、条件、循环计数与寻址状态
Cache 接口 分离的 L1I/L1D,统一的 L2;L2 可配置 TCM 区域 L1I 服务取指,L1D 服务普通 scalar 数据访问;容量由芯片实现决定

执行单元见 V79 core 手册 §1.1(第 7–8 页),寄存器见 §3(第 12–16 页)[1]。寄存器保存状态,运算由执行单元完成。例如,Load 把数据送入 R2,X unit 使用 R2 与 R3 做加法并写入 R4,Store 再把 R4 写回内存。

“scalar”也不表示只能一次计算一个数。基础 Hexagon 指令可在 32/64-bit 通用寄存器内做 packed SIMD;HVX 提供独立的宽向量寄存器与运算资源。ALU 表示算术与逻辑运算,FP 表示浮点运算,MAC 表示乘加累积,即 acc ← acc + a × b。一个 X unit 内的这些名称列出其功能,具体并行度由指令与资源约束决定[1]。

图中的 S0/S1/S2/S3 是四个 slot 编号的简写;在 scalar 结构图里分别标到两个 LD/ST 与两个 X unit 上,用于和手册的分组规则对应。Scalar Load 使用 load/store 相关位置,XTYPE 运算使用 slot 2/3,部分普通 32-bit ALU 指令可用 slot 0–3。因此,S0/S1 并非只能做访存,S2/S3 也不能理解为任意两项运算都能同时执行。只有两个 load 单元,三个普通 load 就不能组成合法 packet[1]。

汇编中的排列还不同于最终二进制排列。Core 手册第 38 页规定,编码按 Slot 3 到 Slot 0 的顺序排列,汇编器按规则处理位置与顺序;空 slot 一般无需手工插入 NOP。具体指令的分组限制仍须逐项满足[1]。

寄存器依赖与组包。

考虑下面这个 packet,假定执行前 R2 为 10、R3 为 20:

{
    R2 = R3
    R3 = R2
}

执行后 R2 为 20、R3 为 10,因为两条指令都读取 packet 开始前的值。它实现交换;若按 C 代码从上到下执行这两次赋值,结果则会不同。这也是 core 手册第 33–34 页用于说明并行语义的例子[1]。

因此,普通数据链可以先按三个 packet 表达:

{ R2 = memw(R0) }
{ R4 = add(R2, R3) }
{ memw(R1) = R4 }

第一包加载的数据供第二包使用,第二包的结果供第三包写回。如果把这三条普通指令直接塞进同一包,加法与 Store 默认读取的是旧 R2、旧 R4,不能得到同样的计算结果。

Hexagon 也提供受限制的包内新值转发机制,例如 new-value store、dot-new predicate,可在规定条件下消费同包新值。Dual stores、dual jumps 也有特殊顺序语义,需要检查具体指令的语义和组合规则,不能机械套用普通寄存器操作的读写模型[1]。

此外,两条普通指令不能随意写同一个目标寄存器;特殊 predicate/control 写入另有规定。组包需要同时核对资源、指令分组、数据依赖、编码顺序与对齐,而非只检查“有没有超过四条”[1]。

1.2.3 HVX 计算:绑定向量状态,发射与执行向量指令

HVX 为 Hexagon 增加宽向量 SIMD 能力。 在 V79 手册描述的 128-byte 模式下,一条向量指令可对 1024-bit 数据中的多个元素执行相同操作。

HVX 指令使用 V0–V31 保存向量数据、Q0–Q3 保存向量掩码,也可以读取 scalar core 的 R0–R31 提供的地址或标量参数,具体取决于指令。 例如,V1 = vmem(R0) 使用 R0 中保存的地址,从内存加载一整段向量数据并写入 V1;R0 保存地址,加载后的向量数据保存在 V1 中[2]。

标量计算指令与 HVX 向量计算指令,在满足 slot、资源与数据依赖等组包规则时,可以放入同一个 packet 并行执行。 两类指令沿用 §1.1 介绍的 packet 语义,由各自的执行资源完成运算;组包时需要同时检查 scalar 与 HVX 的限制[1][2]。

按照 §1.2.1 的绑定关系,Q6 sequencer 取出某个 hardware thread 的 HVX 指令后,HVX 使用该线程所绑定 context 的 V/Q 状态完成操作。不同线程的 V/Q 状态可以分别保留,实际计算则受执行资源和访存能力限制[2]。

表 4|HVX 的线程状态与执行资源

类别 内容 含义
Vector register file 每个 context 的 V0–V31,在本页模式下每个 128 B 保存该线程的向量操作数、结果与累加值
Predicate register file 每个 context 的 Q0–Q3,每个 128 bit 保存向量掩码,用于选择、条件写出等操作
Memory resources load、store 在向量寄存器与内存之间读写;普通 VMEM 访问连接 L2,不经过 L1D
Compute resources shift、permute/shift、两个 multiply 资源 表达 packet 内的运算资源限制;部分 ALU 指令也映射到这些资源

Context 的定义与绑定见 HVX 手册 §1.2(第 5–6 页),VMEM 缓存路径见 §4.9(第 16 页),资源模型见 §5.1(第 20–22 页)[2]。

Scalar 的 P0–P3 与 HVX 的 Q0–Q3 同样需要区分:P 用于 scalar 条件执行等操作,普通 scalar 条件指令检查其最低 bit;Q 保存宽向量 mask。基础 packed SIMD 也可使用 P 的多个 bit,因此 P 的用途不只限于分支。Q6_ 前缀也不能单独用于判断 intrinsic 属于 scalar 还是 HVX,应看操作数与指令类别[1][2]。

HVX 的 slot 与运算资源。

Slot 与 HVX 运算资源也需要分别核对。 V79 HVX 手册第 22 页规定,对齐 vector load 可用 slot 0 或 1,对齐 vector store 使用 slot 0,vector multiply 使用 slot 2 或 3。Vector multiply 占 slot 2/3 时,实际运算仍由 HVX multiply 资源承担[2]。

Scalar 加法与 HVX 向量加法使用不同 slot、各自交给相应执行资源,就是这种分工的例子;示意分配为 Slot 3 和 Slot 2,仍要满足两类指令各自的约束[1][2]。

HVX 手册 §5.1 用 load、store、shift、permute/shift 各一个资源和两个 multiply 资源说明 packet 的组合限制。某些 ALU 指令映射到 shift、permute 或 multiply 资源;一条指令还可能同时占多个资源,例如特定 halfword multiply 会占用两个 multiply 资源[2]。

因此,检查一个 HVX packet 至少有两步:先看各指令能否分配到合法 Hexagon slot,再看它们的 HVX 资源占用是否冲突。拥有空 slot,不代表所需 multiply 或 permute 资源仍可用。

Context 数量解决多个线程如何保持向量状态;packet 规则解决同一组指令如何合法组合;每周期发射与完成多少工作,还取决于实现、线程竞争、指令占用与内存等待。三者不能直接相乘后当作全芯片吞吐。

HVX 还提供 .tmp load 与 .new store 等特殊路径:前者可将加载数据直接供同一 packet 使用,后者可写出同一 packet 新产生的向量结果。是否能利用这些路径,仍要逐条检查指令及其组包约束[2]。

1.2.4 HMX 计算:发射矩阵指令,使用专用矩阵资源

HMX 是矩阵计算协处理器,围绕矩阵操作数、乘加累积与结果转换组织工作。 在一个矩阵 kernel 中,scalar 指令处理地址、尺寸、循环与操作配置,HVX 可处理向量计算和数据重排,HMX 承担适合它的矩阵乘加。按照 §1.2.1 的区分,运行 kernel 的是 Hexagon hardware thread,HMX 是这条执行路径使用的专用矩阵资源;HMX 的内部状态不应直接按 scalar thread 或 HVX context 的数量复制计算。

HMX 的取指仍由 Q6 sequencer 完成。 当程序执行到 HMX 指令时,Q6 取出并解码相应 packet,相关操作读取 scalar registers 提供的地址和配置,再交由 HMX 读取 VTCM、执行矩阵操作并更新 HMX 内部状态。HMX 是承担计算的协处理器,hardware thread 则是运行这段程序的执行路径[3]。

HMX 提供矩阵计算资源,发出相关指令的程序仍运行在 Hexagon hardware thread 上。 V81 手册将 HMX 定义为 SIMD 协处理器,相关指令读取 scalar registers 提供的配置。不能从图中的一个 HMX 方框推导出“只有一个 hardware thread”,也不能假定每个 scalar hardware thread 都有一套独立的 HMX accumulator。公开手册在这里未给出与 HVX 相同的多 context 绑定模型;线程间如何使用 HMX、如何管理其状态与并发,需要对应芯片和运行时的资料[3]。

V81 HMX 手册 §2.1–§2.2(第 4–5 页)描述的 FP16 数据流为:从 VTCM 读取 activation 与 weight,执行矩阵乘加并保存在 HMX accumulator 中,再进行结果转换和写回。相关指令使用 scalar registers 配置地址与操作字段[3]。

表 5|HMX 的主要编程状态与操作

对象 用途 程序如何使用
VTCM 操作数 保存 activation、weight 及转换参数 安排矩阵布局与地址,发出相应加载和运算指令
Accumulator registers 保存矩阵乘积和 执行初始化与矩阵乘加操作
Bias registers 保存转换使用的 bias/scale 等参数 加载转换所需参数
Convert-state registers 保存转换状态 执行 convert transfer 与 write convert state,将结果写回 VTCM

这些对象通过专门指令使用,访问方式不同于 R0–R31 通用寄存器。Scalar registers 提供配置,也不意味着矩阵元素必须先逐个进入 R 寄存器再相乘。V81 手册这里只展开 FP16;V79 的具体编程入口与版本限制见手册索引 §3[3]。

HMX 操作也可以显式组成 packet,但不能套用 HVX 的 slot 表。 固定版本的 llama.cpp HMX_LOAD_MPY_F16 宏把 activation 与 weight 两条加载操作写在同一组花括号中。按其形式替换为示例寄存器后,可以看到如下 packet[4]:

{
    activation.hf = mxmem(R0, R2)
    weight.hf = mxmem(R1, R2)
}

R0、R1 提供操作数地址,R2 提供相应范围配置;它们是 HMX 指令读取的 scalar 操作数。V81 手册说明 activation 与 weight 操作共同组成矩阵乘加过程;这个过程由 HMX 执行[3]。

上述源码确认了显式组包的写法,未直接给出这两条指令各占哪个 slot。所查 V81 HMX 手册也未提供类似 HVX 的 slot 映射表,因此本页不把它们标成 Slot 0/1 或 Slot 2/3,也不推断可以继续加入任意 scalar/HVX 指令。具体 slot 与合法混包组合应以目标架构的汇编器检查、生成编码和反汇编为准[3][4]。

v79-cdsp-capacity. 项目归档的 V79 Compute DSP 原始配置查询(2026-09-13,sysMonApp 10.0.29)报告 Max HW Threads : 8、HVX Units : 6。2026-10-15 的独立 resource 实验再次查询到 6 个 128B HVX units,且 6 个 worker 均成功获取 HVX lock、通过正确性检查;8-thread 上限引用历史配置查询,本轮 resource 未重新查询该字段。 ↩

参考文献

[1] QUALCOMM TECHNOLOGIES, INC. Qualcomm Hexagon V79 Programmer Reference Manual[EB/OL]. 80-N2040-60, Rev. AB, (2025-01-16)[2026-10-15]. https://docs.alexrp.com/hexagon/hexagon_v79.pdf

[2] QUALCOMM TECHNOLOGIES, INC. Qualcomm Hexagon V79 HVX Programmer Reference Manual[EB/OL]. 80-N2040-61, Rev. AB, (2025-01-16)[2026-10-15]. https://docs.alexrp.com/hexagon/hexagon_v79_hvx.pdf

[3] QUALCOMM TECHNOLOGIES, INC. Qualcomm Hexagon V81 HMX Programmer Reference Manual[EB/OL]. 80-N2040-62, Rev. AA, (2026-03-19)[2026-10-15]. https://docs.alexrp.com/hexagon/hexagon_v81_hmx.pdf

[4] GGML-ORG. llama.cpp Hexagon backend: HMX load-store packetization[EB/OL]. (2026)[2026-10-15]. https://github.com/ggml-org/llama.cpp/blob/c114bd4c58a9a39eeb50f115418389a195fdd697/ggml/src/ggml-hexagon/htp/hmx-utils.h#L208-L228

results matching ""

    No results matching ""