Page 483 - 《软件学报》2025年第8期
P. 483
3906 软件学报 2025 年第 36 卷第 8 期
结束后, 对于各个核 AM 中的数组以向量的形式循环执行计算, 将该核子数组规约到一个 1 024 位宽的向量中 (图 8
中框内部分).
3.6.1.2 VPU 内规约
通过上述方法, 我们在 24 个 DSP 核上都得到了对应分区的规约结果并且保存在对应 VPU 的一个 VPE 上.
对于双精度 (double) 的数据, 可以直接使用 mov_from_svrX 接口, 将 VPE 中 16 个数卸载到 SVR 寄存器进行合并.
然而, 对于单精度浮点数, 由于 VPE 的最小访存单位为 64 位, 因此无法直接进行对应的操作. 同图 7 中的思路, 本
文先将取出来的 64 位解包成 2 个对应的单精度浮点数, 再进行合并.
3.6.1.3 DSP 簇核间规约
经过以上两步, 我们在 N 个计算核上分别得到了对应分段的规约结果, 保存为 N 个标量值. 进一步, 本文实现
了多核之间的数据规约算法. 由于核间的规约需要在核间交互数据, 而多核可共享的 DDR 又是带宽受限的. 因此,
利用 GSM 缓存比 DDR 内存访存带宽更大的特性, 本文将子数组规约结果和核间规约的临时共享地址
shared_mem 都创建在所有核共享的 GSM 缓存中, 以减少对 DDR 的频繁访存.
具体来说, 本文将 DSP 簇中的不同核分成若干个子组, 每个子组内的计算核执行一定的归约操作 (例如求和),
然后将子组的结果进行合并, 得到一个较小的结果集合. 然后再将较小的结果集合分成若干个子组, 重复上述操
作, 直到最终只剩下一个结果. 核间数据规约算法流程见算法 3. 其中, core_num 代表本机规约使用的核心数,
shared_mem 是位于 GSM 的中间变量存储地址, warp_size 是常量, 一般为 32.
算法 3. 核间数据规约.
输入: core_num, sub_reduce, shared_mem, warp_size;
输出: sub_reduce.
1. FOR each core DO in parallel:
2. int coreID = get_thread_id();
3. FOR i = (warp_size >>1) TO 0 STEP >>=1 DO:
4. shared_mem[coreID] = sub_reduce
5. barrier;
6. int temp = coreID+i<core_num?shared_mem[coreID+i] : 0;
7. Reduce_op(sub_reduce, temp);
8. END
9. END
3.6.2 基于规约的算子实现
3.6.2.1 sum 以及 softmax
基于上述的规约算法, 开发人员自然而然可以实现 sum 算子. 对于 softmax 算子和 log_softmax 算子, 我们首
先给出其计算公式:
exp(x i − x max )
σ SM (x i ) =
K ∑
( )
exp x j − x max
j=1 (4)
K
∑
( )
σ LSM (x i ) = (x i − x max )−log exp x j − x max
j=1
区别于原始的 softmax 公式, 本文将 e 的指数减去所有输入的最大值, 缩放成小于等于 0 的数, 防止造成数值
溢出. 反向传播可由:

