Developers
Download
[object Object][object Object]
[object Object]
[object Object]

【优先级】低

【描述】整数除法指令在AI处理器上相比乘法和移位,执行开销显著更高。当除数固定时,可以使用基于乘法和移位的快速除法算法,在SIMD中根据除数预计算乘法魔数magic和移位量shift,在SIMT并行计算中使用乘法和移位操作,得到与普通整数除法一致的结果,从而降低每次除法的执行开销。

【样例介绍】以uint32类型整数除法算子为例,算子功能为将输入input的每个元素除以固定除数divisor,并将结果写入输出output。样例对比在SIMT中直接使用普通除法,以及针对固定除数预计算magic和shift后使用乘法和移位替代普通除法的性能差异。完整的算子实现代码请参考

表1 样例规格

[object Object]undefined

SIMT线程层次结构为:

  • Kernel启动线程块数:4096
  • 单次SIMT VF调用线程数:2048

【反例】

基于SIMT的普通整数除法实现:对应样例中的场景0(SCENARIO_NUM=0)。在该场景中SIMT每个线程处理1个元素,并直接使用执行开销较高的普通除法完成计算,代码如下。

[object Object]

场景0和场景1采用相同的数据搬运和写回流程:每个线程块将负责处理的对应数据从GM搬运到UB,在SIMT VF中完成计算并将结果写入UB,随后在核函数中将结果从UB写回GM。两个场景的性能差异主要来自SIMT计算过程中的除法实现方式。

【正例】

基于SIMD与SIMT混合编程的快速除法实现:对应样例中的场景1(SCENARIO_NUM=1)。当除数固定时,可以在SIMD编程中预先计算所需的magic和shift,再在SIMT编程中使用乘法和移位组合运算的方式替代普通除法。

对于uint32类型整数除法,可作如下变形,将除法计算转换为乘法和移位操作:

nd=nd×2s2s=2sd×n2s=m×n2s\left\lfloor \frac{n}{d} \right\rfloor = \left\lfloor \frac{n}{d} \times \frac{2^s}{2^s} \right\rfloor = \left\lfloor \frac{2^s}{d} \times \frac{n}{2^s} \right\rfloor = \left\lfloor {m} \times \frac{n}{2^s} \right\rfloor

其中 nn 为被除数,dd 为除数,m=2sdm = \frac{2^s}{d}nn 除以 2s2^s 可通过右移 ss 位实现。为了避免 m×nm \times n 乘法溢出,将 mm 拆分为:

m=(m232)+232m = (m - 2^{32}) + 2^{32}

magic=m232magic = m - 2^{32},代入上式可得:

nd=n×magic+n×2322s=(n×magic232+n)>>(s32)=(n×magic232+n)>>shift\left\lfloor \frac{n}{d} \right\rfloor = \left\lfloor \frac{n \times {magic} + n \times 2^{32}}{2^s} \right\rfloor = \left\lfloor \left(\frac{n \times magic}{2^{32}} + n\right) >> (s-32) \right\rfloor = \left\lfloor \left(\frac{n \times magic}{2^{32}} + n\right) >> shift \right\rfloor

其中magic和shift即为快速除法所需的乘法魔数和移位数。magic和shift的计算只与固定除数有关,可以在SIMD中预计算,在SIMT计算过程中复用,相关代码如下。

[object Object]

在SIMT计算过程中,每个线程读取待处理的被除数value,调用__umulhi(value, magic)获取value与magic乘积的高32位结果q,再对value + q右移shift位,得到与value / divisor等价的结果。关键代码如下。

[object Object]

【性能对比】

在线程块数相同、输入输出规格相同、均使用SIMD搬运接口完成GM与UB之间数据搬运的情况下,对比场景0和场景1的性能数据如下。

[object Object]undefined

相比场景0,场景1使用乘法和移位替代普通整数除法,Task Duration从110.167μs降低至98.235μs,端到端耗时下降约10.8%。aiv_vec_time从40.685μs降低至22.497μs,下降约44.7%,说明将普通除法替换为乘法和移位后,计算指令耗时明显降低。aiv_scalar_time从10.701μs增加至12.707μs,主要原因是快速除法需要在Scalar计算单元中额外计算magic和shift;但Task Duration仍然下降,说明快速除法带来的计算收益可以覆盖Scalar计算开销。

【总结】对于除数固定的SIMT整数除法场景,可以在SIMD中预计算乘法魔数magic和移位量shift,并在SIMT计算过程中复用。通过将普通整数除法替换为乘法和移位操作,可以有效降低除法计算开销。