Page 19 - 《软件学报》2021年第8期
P. 19

蔡雨  等:异构 HPL 算法中 CPU 端高性能 BLAS 库优化                                              2301


                 4.3   并行化问题
                    多线程并行化并不是总会对计算带来帮助,为了进一步提高性能,需要综合考虑以下问题.
                    (1)  动态多线程
                    创建和启动多线程的开销在计算量很小的情况下会变得突出,从而导致程序性能下降.所以需要设置一个
                 或多个特定的阈值来进行线程数的切换.具体是设置一个阈值将多线程直接切换到单线程,还是设置多个阈值
                 将线程数分段递减,需要具体的 BLAS 函数结合特定的输入数据进行大量的测试归纳(profiling).在 DGEMM 的
                 多线程优化中,我们设计了精确的运算量模型.DGEMM 需要计算一个 m×k 阶矩阵 A 和 k×n 阶矩阵 B 的乘积,
                 其主要计算量和乘积 mkn 成正比.考虑到矩阵 A 的规模 m·k,矩阵 B 的规模 k·n 等都对最终运算性能造成影响,
                 我们使用最小二乘法拟合矩阵计算的性能公式,假设不同线程数目下运算时间根据式(2)计算.
                                        T =  a mkn a mk+  +  a mn a nk+  +  a m a n a k+  +  +  a     (2)
                                            1     2     3    4    5    6   7   8
                    于是对于输入参数为 m i 、k i 和 n i ,运行时间为 t i 的测试数据,对应拟合数据中的一行如式(3)所示.
                                                                ,
                                                         ,
                                                             ,
                                                (m k n m km n n km i , , ,1n k i  )                   (3)
                                                     ,
                                                           i i
                                                       i i
                                                                    i
                                                  i i i
                                                              i i
                    所有这些拟合数据组成 N×8 阶矩阵 P,其中 N 是采样数,而所有的采集时间构成对应的列向量 b,于是构成
                 式(4)的拟合方程.
                                                         T
                                                               T
                                                        P Px =  P b                                   (4)
                    解方程得出的 8 阶变量 x 的各分量就是 a 1 ,a 2 ,…,a 8 的最小二乘拟合结果.分别对单线程、4 线程、8 线程和
                 32 线程测试拟合公式,在运行中根据拟合结果动态切换线程数据,得到如图 10 所示的性能结果.




                                       Fig.10    Performance speedup of DGEMM in 32 threads
                                          图 10  DGEMM 在 32 个线程中的性能加速比

                    实践中还发现,不同的 kernel 实现方式以及硬件设置等因素也会影响到阈值的选取.比如,在异构 HPL 的
                 DGEMV 函数的优化过程中,根据不同的“OMP_NUM_THREADS”、不同的 CPU 主频以及矩阵 A 的列数 N(M
                 方向做并行)设置不同的多个阈值.
                    (2)  均衡余量(remainder)处理
                    当使用多线程将求解问题切分成多块后,往往会遇到不能均分的情况.所谓不能“均分”,是指整体的运算量
                 不能均匀地分配到每个线程中去.此时有两个选择:或者将所有多出的运算量全部放到某一个线程中,比如最后
                 一个线程;或者将余量再次均分到所有线程中.Remainder 处理的问题在线程数较少时(比如 6 个线程)不会那么
                 关键,但在线程数较多时(比如 32 个线程)会变得突出.因为此时的木桶效应更加明显,整体运算的同步结束取决
                 于拥有最大余量的那个线程.根据本文 HPL 算法测试分析后,采取了将 remainder 分配给每个线程处理,得到的
                 性能结果最优.
                    (3)  循环展开与多线程的均衡
                    循环展开的程度和线程的数量需要均衡考虑.在使用动态多线程去加速运算的过程中,往往会有多种求解
                 方法去完成同一个运算.考虑以下场景:异构 HPL 中的 DGEMM 运算在 M 较小时,比如 M=28,此时可以使用 4
                 个线程各处理 6 个 M 维度的行,然后使用 1 个线程处理剩下的 4 个 M 行;或者使用 5 个线程各处理 5 个 M 维
                 度的行,然后使用 3 个线程处理各处理一个 M 行,如式(5)所示.
   14   15   16   17   18   19   20   21   22   23   24