Page 481 - 《软件学报》2025年第8期
P. 481
3904 软件学报 2025 年第 36 卷第 8 期
11. END
12. vector_store(C[offset+i]) //将结果保存到 DDR;
13. END
14. END
在算子中根据输入输出以及计算中间结果的大小, MaxVectorCount 可以取 128, 256, 512 或 1024. 一个 VPE
中集成了 3 个浮点乘加计算单元, 为了充分利用处理器 VLIW 的性能, 在实现时要将加减操作 (a–b) 转换为乘加
和乘减 (a×1–b) 操作.
对于计算过程中的常数变量, 本文通过 Hthreads 的广播指令将其广播成 VPU 中的一个向量常量. 然而由于硬
件的特性, 存储器一次可处理的最低位宽为 64 位, 单个单精度数据并不支持广播. 本文使用 C 语言中的联合体
union 实现 32 位常数到 64 位的打包和解包, 它允许将多个不同类型的成员变量存储在同一个内存空间中. 一个
union 的长度为 64 位宽, 代表 1 个双精度浮点数或者长度为 2 的单精度浮点数组. 实现代码如图 7 所示.
图 7 单精度浮点数打包
3.5 激活函数及其反向传播算子实现
激活函数可以使模型更加稳定, 显著提高模型性能, 是深度神经网络中不可缺少的模块. 本文实现了语言模型
中最常用的两个激活函数.
ReLU 激活函数是一种常用的非线性函数, 其表达式为 y = max(x, 0), 具有计算速度快, 训练过程稳定的特点,
因此广泛运用在深度学习模型中. ReLU 前向传播和反向传播公式为:
ReLU (x) = max(0, x)
(1)
dx = (y > 0) ? dy : 0
由于硬件位宽限制, 向量 C 接口的条件赋值语句仅支持双精度数据. 对于单精度下的 ReLU 反向传播中的条
件赋值操作, 本文采用位运算实现 res = (A>B) ? C : D, 得益于 VLIW 的架构, 取得了明显的加速效果, 见算法 2.
算法 2. 基于位运算的条件赋值方法.
输入: A, B, C, D;
输出: res.
1. vo = gt(A, B); //判断是否赋值
2. vzero = mov 0 to VPEs; //构造全 0 向量
3. vot = sub(vo, vzero); //条件向量格式化为全 0 或全 1
4. x64 = (lvector unsigned long int)C;
5. y64 = (lvector unsigned long int)D;
6. vo64 = (lvector unsigned long int)vot; //强制类型转换
7. //位运算赋值

