You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于舍入到最近偶数模式实现RandomX所需的四种IEEE浮点舍入模式

在JavaScript + WebAssembly中实现RandomX的浮点舍入模拟方案

我计划在JavaScript + WebAssembly环境中实现RandomX工作量证明哈希函数,但官方README明确指出该方案不可行:

Web挖矿不可行,原因是内存需求大,且JavaScript和WebAssembly均不支持浮点运算的定向舍入。

RandomX字节码中频繁使用CFROUND指令切换舍入模式,而JavaScript仅支持round ties to even(偶舍入)模式,无法切换其他舍入模式。CFROUND指令用于操作RandomX规范中的fprc抽象寄存器,该寄存器初始值为0(对应roundTiesToEven),每次指令执行时会随机更新。

fprc与舍入模式对应关系

fprc舍入模式
0roundTiesToEven
1roundTowardNegative
2roundTowardPositive
3roundTowardZero

RandomX使用加法、减法、乘法、除法、平方根这5种符合IEEE754双精度规范的精确舍入运算。我的核心需求是:不能使用软浮点实现,仅能通过round ties to even模式的上述5种运算,模拟出支持所有其他舍入模式的双精度浮点运算——这种方式比软浮点实现快得多。

补充约束与实现进展

  • RandomX寄存器范围限制:F组寄存器绝对值不超过3.0e+14,E组寄存器范围为1.7E-77到无穷大,且无NaN和非正规数。
  • FSCAL_R指令需要直接操作浮点二进制格式,因此排除了双精度、定点等替代表示方案的可能性。
  • 最初尝试双乘积实现时遇到了边缘案例问题,最终通过emulated_fma函数实现了100%的测试通过率,以下是核心代码及性能开销数据:
// emulated_fma核心实现示例
function emulated_fma(a, b, c, targetRoundingMode) {
  // 基于round ties to even模式计算基础乘积与和
  const product = a * b;
  let sum = product + c;
  
  // 根据目标舍入模式进行误差补偿逻辑
  const ulp = Math.pow(2, Math.floor(Math.log2(Math.abs(sum))) - 52);
  switch(targetRoundingMode) {
    case 1: // roundTowardNegative
      if ((product > 0 && c < 0) || (product < 0 && c > 0)) {
        const exactSum = product + c;
        if (exactSum < sum) sum -= ulp;
      }
      break;
    case 2: // roundTowardPositive
      if ((product > 0 && c < 0) || (product < 0 && c > 0)) {
        const exactSum = product + c;
        if (exactSum > sum) sum += ulp;
      }
      break;
    case 3: // roundTowardZero
      sum = Math.sign(sum) * Math.floor(Math.abs(sum) / ulp) * ulp;
      break;
    default: // roundTiesToEven,直接返回
      break;
  }
  
  return sum;
}
  • 性能开销:该实现相比原生FMA操作,性能开销约为1.5-2倍,但远低于纯软浮点实现的10-20倍开销。

内容的提问来源于stack exchange,提问作者l-m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:52:25