【问题标题】:128x128 bit multiplication on for x86 CPUx86 CPU 开启 128x128 位乘法
【发布时间】:2015-04-15 18:30:15
【问题描述】:

在我的应用程序中,我需要一个快速的 128x128 位乘法(结果 = 256 位)。是否有任何 x86 优化库可以执行此操作?

【问题讨论】:

标签: gcc x86 inline-assembly multiplication


【解决方案1】:

有 GNU GMP 库 - https://gmplib.org/ 应该对长整数有很好的优化乘法。它具有基准https://gmplib.org/download/misc/gmpbench-0.2.tar.bz2,可用于测试 128x128 大小写(multiply.c,args 128 128)

对于固定大小,您可以尝试 GMP 的低级接口 - mpn https://gmplib.org/manual/Low_002dlevel-Functions.html

功能:mp_limb_t mpn_mul (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t s1n, const mp_limb_t *s2p, mp_size_t s2n) 将 {s1p, s1n} 和 {s2p, s2n} 相乘,并将 (s1n+s2n)-limb 结果写入 rp。返回结果中最重要的部分。

目标必须为s1n + s2n 分支留出空间,即使产品的最重要分支为零。目的地和任一来源之间不允许重叠。

该函数要求s1n大于等于s2n

对于一些特殊情况,haswell 声称速度为 1.57-1.8 个周期/肢体(“通常肢体包含 32 或 64 位”) http://code.metager.de/source/xref/gnu/gmp/mpn/x86_64/coreihwl/mul_1.asm#35

【讨论】:

  • 存在mpn_mul_n,因为两个操作数的大小相同。
【解决方案2】:

如果您只需要快速的 128x128 位乘法,则可以自己完成。

在 32 位 CPU 下需要 16 个(32*32 位)乘法,在 64 位 CPU 下需要 4 个(64*64 位)乘法。

32位CPU(使用32位乘法)下的算法是:

假设 ABCD 和 EFGH 表示两个 128 位数字,任何字母表示一个 128 位数字的 32 位数字。

ABCD * EFGH =  
  ABCD * E * 2^96 //Multiplication with 2^96 is 96 left shift or mov for 3 32bit digits 
+ ABCD * F * 2^64 
+ ABCD * G * 2^32 
+ ABCD * H 

其中 n 是 32 位数字。

ABCD * n =  
  A * n * 2^96 //Multiplication with 2^96 is 96 left shift or mov for 3 32bit digits
+ B * n * 2^64
+ C * n * 2^32 
+ D * n

【讨论】:

  • 许多 ISA 提供扩展乘法(32x32 => 64 位在一对寄存器中),例如x86、ARM 和 MIPS。 (一些精简的 ARM 内核只有窄 mul)。在 C 中,编译器通常知道如何将a * (uint64_t)b 优化为扩大乘法。 (但是当你试图让编译器发出 adc add-with-carry 时,C 的问题就出现了)
猜你喜欢
  • 2018-05-22
  • 2015-07-05
  • 2011-09-07
  • 2018-07-18
  • 1970-01-01
  • 2012-04-05
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多