【问题标题】:Floating vs Fixed point numbers and performance浮点数与定点数和性能
【发布时间】:2012-12-25 06:41:23
【问题描述】:

我很好奇浮点运算在专用硬件和固定硬件上的速度有多快。

对于定点,假设您有数字 555,并且您想乘以 1.54,您需要将值 555、154 和 100 加载到寄存器中(三个时钟),将 555 乘以 154(四个时钟),然后除以 100(四个时钟),然后将输出寄存器加载到内存中(一个时钟)。

使用浮点,您可以将值 555 和 1.54 加载到寄存器中(两个时钟),获得更大的缩放/指数(一个时钟),减去缩放(一个时钟),归一化(四个时钟进行乘法运算) ),乘法(四个时钟),然后将输出寄存器保存到内存中(一个时钟)。

12 个固定时钟和 13 个浮动时钟。那么我是否遗漏了一些东西,并且有真正的性能优势,还是只是易于使用?我只是使用了四个时钟进行乘法,显然它不会在所有处理器上都相同,但它提供了一个大致的概念。

【问题讨论】:

  • 显然,对于那些您不提前知道扩展并且需要将其打包成具有专用硬件至关重要的数量的操作,但这类操作通常非常罕见......
  • 嗯,我没有考虑位移。在固定方面,您可以位移而不是除以 100(必须转换为基数 2 而不是基数 10)。所以固定端的时钟可能低至 10 个时钟,那是不确定的。不要认为你可以在浮点上进行位移,因为指数都是以 10 为底的。

标签: floating-point fixed-point decimal


【解决方案1】:

使用定点数 1.54 已经以适合您的格式存储。然后,您只需进行整数乘法,然后进行常数加法以补偿舍入误差和一些筛选以使基数正确。见Wikipedia:Q number format

例如假设 Q15.16 格式(整数 15 位,小数部分 16 位),您可以像这样执行乘法:

int32_t a = 555 * (1 << 16);  /* constant */
int32_t b = 1.54 * (1 << 16); /* constant, no calculations needed at run time */

int64_t temp = ((((int64_t) a) * b) + (1 << 15)) >> 16;
int32_t result = (int32_t) temp;

1.54 转换为b 不需要除法或其他计算(除非您需要从外部读取输入)。假设 CPU 有两个负载、双精度乘法、常数加法(如果一次执行多次乘法,则已经在寄存器中)和移位。

使用专用硬件(例如 DSP 内核或指令扩展)将直接支持某些 Qn.m 类型,也可以采用矢量化方式。尽管使用更高级别的 CPU(现代 Intel 或 AMD),但我相信使用定点可能没有太大的好处,因为浮点指令已经非常有效。

【讨论】:

  • 假设您甚至需要从内存中检索并保存到内存中,因此固定乘法最多需要 9 个时钟。那么,专门的浮点单元是否只是因为使用浮点编程更容易?
  • 我相信现代 CPU 使用浮点并不重要,除非您能够并且想要向量化您的计算(例如,使用特定于机器架构的 gcc 内在函数)。如果您的 CPU 不支持硬件中的浮点数(例如低端 ARM 和 MIPS),则使用定点非常有意义。
【解决方案2】:

对于现代处理器,查看单个指令的性能并不是很有用。许多指令都是pipelined 和超标量,因此多条指令处于同时执行的不同阶段。

从处理器规格和代码计算性能非常困难。我通常只会这样做来估计尚不存在的处理器的性能。如果处理器和代码都存在,则更容易衡量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 2011-11-23
    • 2013-03-26
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2017-11-16
    相关资源
    最近更新 更多