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 这一层级的编程模型有着很大的挑战. 我们将在后续的
   474   475   476   477   478   479   480   481   482   483   484