assembly 为什么RISC-V没有指令计算执行?

o0lyfsai  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(111)

我需要在RISC-V上处理bignum计算(加法和减法,但我将减法视为等同于有符号加法),情况有点复杂。我从半个小时的互联网研究中收集到的信息:

  • RISC-V操作不提供检查进位或溢出的方法
  • 这一决定的动机是,标志或其他处理它的方法给乱序微架构增加了很多复杂性。
  • 相反,他们建议做分行后
  • 对于无符号加法,溢出处理可以用一个bltu来完成。
  • 如果其中一个操作数的符号已知,则对有符号加法也是如此
  • 否则,需要执行两次检查(三个附加指令)
  • 互联网上的人们对此感到愤怒(我不会在这里链接)

据我所知,这些分支确实很好地覆盖了大多数场景,除了一个:bignum addition(签名)因为在那里,我们遇到了热循环中最慢的检查路径。
我对伊萨设计只知道一点点,但是为什么他们不包括一个计算(a + b) >> 32的指令(有效地执行)?有点像乘法指令如何被分成mulmulh。这将允许总是用两个指令进行所需的计算。更强大的微架构甚至可以检测序列,只做一次加法。
我是否错过了一些技巧,使这条指令过时(或等同于它)?它是否有任何重大的缺点,我监督?我没有找到很多关于这个主题的好文档。

iszxjhcz

iszxjhcz1#

add/sltu给你求和和进位:https://godbolt.org/z/Y7f5dzj1P显示GCC使用它进行无符号数学:sum=a+b / carry = sum<a。或用于__builtin_uadd_overflow
但问题是缺乏ILP:在add结果准备好之前,sltu不能启动。如果你能像你提议的那样直接从输入中得到执行,这个问题就可以解决;说得好当然,ADD/SLTU的融合也可以解决这个问题;也许这就是建筑师的想法
在创建一条根据2输入加法的进位输出产生01输出的指令时,我没有看到任何CPU设计挑战。那很容易构建32或64位加法器以支持X1 M9 N1 X指令的任何方式都可以容易地从高位产生进位输出信号。事实上,这可能就是sltu读取的内容,因为整数ALU使用单个binary adder-subtractor是正常的,其中一个输入为NOT,一个进位为1来实现减法。(低位是全加器而不是半加器,否则是正常的二进制加法器。
对于大于2个reg-width的bignum,另一个主要问题是执行带进位-in 的加法(在带有进位标志和带进位加法指令的ISA上)。
更糟糕的是,从3个输入的加法中得到进位。(其中的任何一部分都可以 Package ,所以AFAIK不可能将其合并组合成一个add和比较。这是adc的纯C实现的一个常见缺陷;在这个链接的答案上的注解有工作C,但它编译效率不高)。
除非有一些我不知道的技巧,我想这就是人们对Bignum的RISC-V和MIPS等无标志设计感到不安的原因。
更新:Alfredola的答案显示了纯C语言,clang将编译成x86-64的add/adc/adc/adc链或其他带有进位加法指令的ISA。对于RV 64(https://godbolt.org/z/oaevGs67q),看起来我们得到了2x sltu和3x add,每个加法步骤都有进位和进位。我不知道这是否是最佳的,clang目前只支持RV 64的_BitInt(128),我没有检查https://gmplib.org/mpn手写asm。

相关问题