Karatsuba-Ofman乘法器是俄罗斯人Karatsuba于1962年提出的,主要思想是采用分治算法计算整数乘法,将计算复杂度向前推进到nlog23n^{log_23},而此前普遍认为整数乘法的计算复杂度是O(n2)O(n^2)
来看一个例子:假设n=2ln=2lx=x12l+x0x=x_12^l+x_0y=y12l+y0y=y_12^l+y_02l2l-位整数,于是:
xy=(x12l+x0)(y12l+y0)xy=(x_12^l+x_0)(y_12^l+y_0)
=x1y122l+[(x0+x1)(y0+y1)x1y1x0y0]2l+x0y0=x_1\cdot y_12^2l+[(x_0+x_1)\cdot(y_0+y_1)-x_1y_1-x_0\cdot y_0]2^l+x_0y_0
xyxy可以通过3个ll-位的整数乘法(而不是2l2l-位的整数乘法)和2个乘法,2个减法算式计算出来。
ll数值较大,加法和减法相对乘法的计算代价可以忽略。在经典算例中,程序可以反复迭代到中位数,并一直执行到满足阈值(可能的值是机器字长度)的条件才停止。
对于大小适中的整数,Karatsuba算法的执行上限是需要考虑的因素。不同于传统方法,Karatsuba算法的执行尽可能减少移位请求(对于2l2^l22l2^{2l}乘法),并且高效使用面向字节的操作。例如:采用拆分字节的边界的方法有可能更好,一个指定阶段的分裂可以拆分成2个以上片段。
例1(Karatsuba-Ofman方法):考虑224-位整数xxyy的乘法,运算设备的字节长度为W=32W=32。2个深度为2的方法展现如下图所示,显然,图a的裂项从数学上看可能更为优雅并且在代码上更具备重用性。然而,却需要更多的移位操作,这是因为裂变并非以字长单位为边界进行。如果56-位数的乘法的代价近似于64-位数乘法,显然裂项对于硬件容量利用不足,这是因为如图b所示,9个64位乘法与1个32位、8个64位乘法的代价完全不同。另外,图b的列项建立在字长单位为边界的基础上,由于存在加法移位,具有更多的复杂的跨项计算。例如,深度为2的跨项具有形式
Karatsuba-Ofman乘法器
上图展示了224-位的整数分裂成深度为2的二叉树。图a所示的xyxy乘积包括采用3个112112112*112位乘法,每个执行又采用3个5656位的乘法。b图所示的xy包括采用一个9696位乘法(列项为一个3232位和2个6464位乘法)和2个128128位的乘法(每个产生3个646464*64位乘法)。
如下:
(x0+x1)(y0+y1)x1y1x0y0(x_0+x_1)(y_0+y_1)-x_1y_1-x_0y_0
其中,x0+x1x_0+x_1y0+y1y_0+y_1在图a为57-位数,在图b为65-位数。虽然(x0+x1)(y0+y1)(x_0+x_1)(y_0+y_1)可以被1个64
64位乘法和2个加法计算出来,图b列项的代价仍然有点大。
Karatsuba-Ofman乘法器
上图展现了192-位整数的深度为2的裂项。图a的乘法xyxy具有3个969696*96的乘法,每个乘法执行1个323232*32和2个646464*64的乘法(每个乘法需要3个32*32位乘法),总共需要21个323232*32位乘法。图b或图c,仅需要18个323232*32位乘法就可以完成计算。
例2(192位数乘法):考虑Karatsuba-Ofman算法应用于192-位整数乘法的例子,假设设备字长W=32W=32。按上图所示的3个深度位2的方法,图a需要21个323232*32位乘法,图b和图c只需要18个。主要的思路是3l3l-位整数x=x222l+x12l+x0x=x_22^2l+x_12^l+x_0y=y222l+y12l+y0y=y_22^{2l}+y_12^l+y_0能够计算如下:Karatsuba-Ofman乘法器
有限域的乘法性能在椭圆曲线机制中是非常重要的。囿于硬件乘法器和传播成本的限制,执行以上算法势必会引起明显的瓶颈。

相关文章: