pie*_*mes 10 assembly instruction-set bignum riscv
我需要在RISC-V上处理bignum计算(加法和减法,但我将减法视为等同于有符号加法),情况有点复杂。我通过半个小时的互联网研究得到的信息:
bltu.据我所知,这些分支确实很好地涵盖了大多数场景,除了一个:(有符号)bignum 加法。因为在那里,我们遇到了热循环中最慢的检查路径。
我对 ISA 设计知之甚少,但为什么他们不包含计算(a + b) >> 32(实际上是执行)的指令?有点像乘法指令被分成mul和mulh的方式。这将允许始终使用两条指令进行所需的计算。更强大的微架构甚至可以检测序列并且只进行一项加法。
我是否遗漏了一些会使该指令过时(或与其等效)的技巧?它有我需要监督的重大缺点吗?我没有找到关于这个一般主题的很多好的文档。
add/sltu为您提供求和和进位:https://godbolt.org/z/Y7f5dzj1P显示 GCC 使用它进行无符号数学:sum=a+b/ carry = sum<a。或者为了__builtin_uadd_overflow
但问题是缺乏 ILP:在结果准备好sltu之前无法启动。add如果您可以按照您的建议直接从输入中获取结转,则可以解决这个问题;好点子。当然add/sltu的融合也能解决这个问题;也许这就是建筑师的想法。
在创建根据 2 输入加法的进位输出生成 a0或输出的指令时,我没有看到任何 CPU 设计挑战。1那会很容易;任何构建 32 位或 64 位加法器来支持add指令的方法都可以轻松地从高位产生进位信号。事实上,这可能就是读到的内容,因为整数 ALU 使用单个二进制加减器sltu是正常的,其中一个输入的 NOT 和一个进位来实现减法。(低位是全加器而不是半加器,否则是普通的二进制加法器。)1
超过 2 个寄存器宽度的 bignum 的另一个主要问题是进行进位加法(在具有进位标志和进位加法指令的 ISA 上)。
\n更糟糕的是,从 3 输入加法中获取进位。(其中的任何一部分都可以换行,因此不可能将其组合成一个添加和比较。这是纯 C 实现的常见陷阱adc;对该链接答案的注释具有有效的 C,但它没有\编译效率不高)。
除非有什么我不知道的技巧,否则我认为这才是真正让人们对无标志设计(例如用于 Bignum 的 RISC-V 和 MIPS)感到不安的原因。
\n更新:\xc5\x98r\xc5\x99ola\ 的答案add/adc/adc/adc显示纯 C,clang 将使用 add-with-carry 指令编译为 x86-64 或其他 ISA 的链。对于 RV64 ( https://godbolt.org/z/oaevGs67q ),看起来我们为每个同时具有进位和进位的加法步骤获得 2xsltu和 3x 。add我不知道这是否是最佳的;clang 目前只支持_BitInt(128)RV64,我没有检查https://gmplib.org/ mpn手写的 asm。