Page 479 - 《软件学报》2025年第8期
P. 479
3902 软件学报 2025 年第 36 卷第 8 期
需要的资源与已有的线程组匹配, 则可以直接调用 hthreads_group_exec 函数进行计算, 无需重新创建线程组. 因
为 hthreads_group_exec 函数的固有开销为约 0.6 ms, 所以使用这种方法可以减少 50% 的固有启动开销.
图 5 Hthreads 线程组单例类图
在算子库层面, MTTorch 采用 CPU+DSP 异构计算设计. 对于核心算子, 采用 MTTorch 的 Hthreads 编程模型
进行并行优化. 对于训练大语言模型时占比极少的算子和并行实现带不来性能优化的算子采用虚拟算子的方法实
现. 虚拟算子是指注册在 DSP 后端但仍使用 CPU 进行计算的算子. 由于一个计算图上所有算子的设备后端需要
是一致的, 因此这类算子需要在 DSP 后端进行注册, 但实际仍在 CPU 端执行.
不适宜并行优化的算子, 主要有内存中非连续的 Tensor 参与计算和 Tensor 数据量过小这两种情况. 非连续
Tensor 难以实现批量访存, 无法充分利用向量处理单元; 输入 Tensor 过小时, 整体计算时间也就是几毫秒的级别,
由于 DSP 线程组启动时有 1 ms 左右的固有开销, 导致其会弱化加速的效果, 甚至没有加速效果. MTTorch 中算子
的执行流程如图 6 所示.
算子调用
是否使用 DSP 优化
是 否
获取 Hthreads 修改 Tensor device 属性
可读地址 void*
执行 PyTorch CPU 算子
执行 Hthreads 核函数 重新修改 device 为 HT
结束调用
图 6 MTTorch 中算子执行流程
此外, 本文将 ftIMM [14] 集成到了 MTTorch 框架中, 通过对 ftIMM::SGEMM 的调用实现了适用于模型训练的
高效 mm 和 bmm 算子. 为了最大限度地利用 DMA 带宽进行数据存取, 用户必须确保每次 DMA 拷贝的内存空间
尽可能连续, 并且大小为 1 024 位的倍数. 因此在 MTTorch 中, 矩阵的存储和遍历均采用了行主序 (Row-major) 的
方式, 以确保数据在内存中的布局与 DMA 的存取方式相匹配, 从而提升数据处理的效率. 由于高效的矩阵乘法实
现需要精心设计, 充分利用指令的流水线, 这对于 Hthreads 这一层级的编程模型有着很大的挑战. 我们将在后续的

