【问题标题】:Why does floating point addition took longer than multiplication为什么浮点加法比乘法花费更长的时间
【发布时间】:2015-07-26 20:15:50
【问题描述】:

我正在使用 PIC18f4550,该程序对速度至关重要。当我将两个浮动变量相乘时,PIC 需要大约 140 个周期来执行乘法运算。我正在用 PIC18f4550 timer1 测量它。

variable_1 = variable_2 * variable_3; // took 140 cycles to implement

另一方面,当我添加相同的两个变量时,PIC 需要 280 个周期来执行添加。

variable_1 = variable_2 + variable_3; // took 280 cycles to implement

我已经看到,如果变量的变化取决于它们的指数,则周期数会有所不同。 这些更多周期的原因是什么?虽然我在想加法比乘法更简单。 有什么解决办法吗?

【问题讨论】:

  • 乘法比加法更容易做,因为移位允许立即加倍,所以 50 x 4 可以非常快速地完成,因为您只需将所有位移位超过 2。50 x 10 将是(50 移动了 3 次(即 50 * 8) + (50 移动了一次 (50 * 2)
  • 您的数据表明该平台上的浮点运算是模拟的。我之前在多个硬件平台(包括 x86 和 ARM)上进行过多个浮点仿真,根据我的经验,如果处理器提供快速整数乘法指​​令,浮点乘法可能比加法更快。加法需要区分多种情况:是有效的加法还是减法?哪个操作数的量级大?指数的差异是大还是小(“近”和“远”的情况)?乘法是直线代码。
  • 我在我的一个浮点仿真包上挖掘了一些历史数据,它表明,在存在快速整数乘法指​​令的情况下,模拟浮点乘法可能比模拟浮点加法。 A paper on floating-point emulation on ARM 显示乘法吞吐量是 双精度 的加法吞吐量的 1.28 倍。您观察到的 2 倍因子在我看来似乎过高,这可能表明加法没有尽可能有效地模拟。
  • 2x 的因子不是恒定的,如果两个变量具有相同的指数,则某些加法需要 850 个周期才能实现其中一些小于 280-。我不能对加法做任何事情来提高效率,在汇编代码中它只是调用一个实现加法的例程。
  • 除了尾数预移位以进行加法外,中间结果也可能需要后移位。 (1.xx * 1yy) 的乘法可能需要右调整 1 位,但带有负加数的通用加法也可能需要多位后移(例如 1.111001 - 1.110001 = 0.001000)

标签: optimization floating-point addition


【解决方案1】:

对于浮点加法,需要调整操作数,使它们在加法之前具有相同的指数,这涉及跨字节边界移动尾数之一,而乘法基本上是将尾数相乘并加上指数。

由于 PIC 显然有一个小型硬件乘法器,因此有时乘法可能比执行多字节移位更快(尤其是如果 PIC 只有单个位移指令),这并不奇怪。

除非处理器直接支持它,否则浮点总是很慢,如果可能的话,您当然应该考虑安排您的代码使用定点。摆脱浮点库可能也会释放大量代码空间。

【讨论】:

  • The reference manual for the PIC18f4550 显示存在 8x8->16 位单周期乘法器。支持移位多字节数量所需的单位循环。根据我对也不支持多位移位的 8086 的经验,很明显,尾数对齐期间所需的移位相对昂贵,但移位应使用寄存器移动的字节移位,仅剩余移位计数(模 8)通过 1 位移位/旋转。因此,虽然预计加法会更慢,但我不认为它会慢 2 倍。
  • 澄清:8086 没有桶形移位器,因此不支持 1 以外的 立即 移位计数。但是,使用微编码循环的指令支持多位移位CL 寄存器,但是它SHR/ROR/RCR reg,1 指令的等效序列。
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 2018-01-04
  • 2015-06-04
  • 2019-07-06
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多