块体执行方式¶
灵犀指令集采用融合计算架构,能够同时支持标量、向量和张量等多种数据类型的运算。基于这一架构特性,我们设计了多种类型的块指令,以满足不同的运算需求。不同类型块指令的块体在执行方式上也各具特点。
当前版本中,拥有块体的块指令支持以下三种执行方式:
| 执行方式 | 说明 |
|---|---|
| 标量模式(Scalar mode) | 块体仅执行一次,适用于标量运算或系统配置操作。 |
| 串行模式(Sequel mode) | 块体重复多次执行,同一组内的迭代允许并行执行,但不同组之间必须按序执行。 |
| 并行模式(Parallel mode) | 块体重复多次执行,所有迭代之间都允许并行执行。 |

核心概念详解¶
执行组(Group)与执行通道(Lane)¶
在串行模式和并行模式下,处理器都会将展开后的所有块体迭代从 0 开始顺序编号。硬件调度单元根据调度策略,从这些迭代中按批次取出若干个,将其分配给一个执行组(Group)来执行。
执行组(Group)是硬件调度的基本单位,表示一组可以在同一时刻被并行执行的块体迭代。
每个 Group 内包含若干条执行通道(Lane):
- 每条 Lane 对应一个独立的硬件执行通路,可以完整执行一次块体迭代;
- Lane 在其所属 Group 内从 0 到
LaneNum - 1依次编号,该编号可视为 Lane 在 Group 内的本地 ID; - 单个 Group 中 Lane 的数量由硬件实现固定决定,软件可通过系统寄存器 LCFR 的
LaneNum字段查询当前硬件支持的 Lane 数量。
同一 Group 内的所有 Lane 以锁步(Lock Step)方式执行:
- 在同一时刻,所有 Lane 执行的是同一条指令流(相同的 PC);
- 各 Lane 仅在所处理的数据(对应的迭代号)上有所区别。
调度和映射关系如下:
- 一个 Group 至少包含 1 条 Lane,通常其 Lane 数量等于硬件支持的最大并行 Lane 数;
- 每次调度时,硬件会将一组连续编号的块体迭代分配给同一个 Group 内的各个 Lane:
- 通常,第
i条 Lane 对应执行第base_iter + i号迭代(base_iter为当前 Group 的起始迭代编号);
- 通常,第
- 当总迭代次数不是 Group 大小(Lane 数)的整数倍时,最后一个 Group 中可能只有部分 Lane 执行有效迭代,其余 Lane 在该 Group 内保持空闲或被屏蔽。

执行方式说明¶
标量模式¶
标量模式适用于执行标量运算或进行系统配置的块指令。在这种模式下:
- 块体仅执行一次,不进行迭代展开。
- 在支持乱序执行的块引擎中,块体指令可以乱序执行。但要求所有块体指令顺序提交,确保执行结果的正确性
- 适用于标量计算、配置寄存器、设置参数等一次性操作。
串行模式¶
串行模式适用于块体展开的不同迭代间处理的数据存在依赖关系的场景。这种模式下:
执行特性:
- 组内并行,组间串行:同一Group内的所有迭代可以并行执行,但不同Group之间必须严格按照顺序执行
- 数据依赖处理:当迭代i的计算结果被迭代j使用时(j>i),这两个迭代必须分配到不同的Group中
- 顺序保证:Group N的所有迭代必须在Group N+1的任何迭代开始前完成
调度机制:
迭代编号:0 1 2 3 4 5 6 7 8 9 ...
Group分配:
┌──Group 0───┐┌──Group 1───┐┌──Group 2──┐
│ 0 1 2 3 ││ 4 5 6 7 ││ 8 9 ... │
└────────────┘└────────────┘└───────────┘
执行顺序:Group 0 → Group 1 → Group 2 → ...
嵌套循环展开:
串行模式和并行模式都使用LB和LC寄存器控制块体的执行次数:
lane_id = 0;
// 三层嵌套循环展开
Parallel_for(LC2 = 0; LC2 < LB2; LC2++)
Parallel_for(LC1 = 0; LC1 < LB1; LC1++)
Parallel_for(LC0 = 0; LC0 < LB0; LC0++) {
kernel(lane_id); // 块体执行,lane_id标识当前迭代
lane_id++;
}
迭代总数计算:CNT = (LB0-LC0) × (LB1-LC1) × (LB2-LC2)
迭代编号规则:ID = LC0 + LC1×(LB0-LC0) + LC2×(LB0-LC0)×(LB1-LC1)
并行模式¶
并行模式适用于块体展开的所有迭代间处理的数据都没有依赖关系的场景。这种模式下:
执行特性:
- 完全并行:所有迭代之间都允许并行执行,没有执行顺序约束
- 独立执行:每个迭代都是独立的,不依赖其他迭代的结果
- 最大并行度:硬件会尽可能同时调度所有迭代到可用Lane上执行
调度机制:
迭代编号:0 1 2 3 4 5 6 7 8 9 ...
并行调度:所有迭代尽可能同时分配到可用Lane
┌─group 0─┐ ┌─Group 1─┐ ┌──Group 2──┐ ┌───Group 3───┐
│ 0 1 2 3 │ │ 4 5 6 7 │ │ 8 9 10 11 │ │ 12 13 14 15 │
└─────────┘ └─────────┘ └───────────┘ └─────────────┘
┌───Group 4───┐ ┌───Group 5───┐ ┌───Group 6───┐ ┌───Group 7───┐
│ 16 17 18 19 │ │ 20 21 22 23 │ │ 24 25 26 27 │ │ 28 29 30 31 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
...(继续直到所有迭代完成)
适用场景:
- 向量加法、乘法等元素级独立操作
- 矩阵中互不依赖的元素计算
- 图像处理中像素级独立操作
总结¶
模式选择指南:
| 特性 | 标量模式 | 串行模式 | 并行模式 |
|---|---|---|---|
| 迭代次数 | 1次 | 多次(LB寄存器控制) | 多次(LB寄存器控制) |
| 迭代间依赖 | 不适用 | 可能存在依赖 | 无依赖 |
| 并行粒度 | 无 | 组内并行 | 完全并行 |
| 执行顺序 | 顺序提交 | 组间顺序 | 无顺序要求 |
| 适用场景 | 标量运算、配置 | 数据依赖的循环 | 数据独立的循环 |
硬件实现考虑:
- Group调度器:负责将迭代分组并分配到执行单元
- Lane分配器:管理每个Group内的Lane资源分配
- 依赖检测:在串行模式下检测跨Group的数据依赖
- 资源仲裁:在并行模式下仲裁多个迭代对共享资源的访问
通过这三种执行模式的灵活组合,灵犀指令集能够高效处理从标量运算到大规模并行计算的各种应用场景,充分发挥融合计算架构的优势。