【发布时间】:2015-04-02 13:11:11
【问题描述】:
为什么在 64 位机器上执行 64 位运算(例如双精度运算)时,与在 32 位机器上执行相比,我们没有看到两倍的性能?
在 32 位机器中,我们不需要从内存中获取两倍的数据吗?更重要的是,执行 64 位操作不是需要两倍的周期吗?
【问题讨论】:
标签: performance memory floating-point cpu-architecture 32bit-64bit
为什么在 64 位机器上执行 64 位运算(例如双精度运算)时,与在 32 位机器上执行相比,我们没有看到两倍的性能?
在 32 位机器中,我们不需要从内存中获取两倍的数据吗?更重要的是,执行 64 位操作不是需要两倍的周期吗?
【问题讨论】:
标签: performance memory floating-point cpu-architecture 32bit-64bit
在 32 位机器中,我们不需要从内存中获取两倍的数据吗?
没有。在大多数现代 CPU 中,内存总线宽度为 at least 64 bits。较新的微架构可能具有更宽的总线。四通道内存将具有最低 256 位总线。许多当代 CPU 甚至支持6 or 8-channel memory。因此,您只需 1 次获取即可获得双倍。除了大部分时间该值已经在缓存中,因此加载它不会花费太多时间。 CPU 每次加载的不是单个值而是整个缓存行
更重要的是,执行 64 位操作不需要两倍的周期吗?
首先,您应该知道 double 中有效位的实际数量是 53,所以它并不“两倍”更难。它是float(24 个有效位)中数字的两倍。当位数增加一倍时,加法和减法的难度增加一倍,而乘法的难度增加四倍。许多其他更复杂的操作将需要更多的努力
但尽管数学工作更难,浮点和双精度的非内存操作在大多数现代架构上通常是相同的,因为两者都将在具有相同 ALU/ 的同一组寄存器中完成FPU。那些强大的 FPU 可以在一个周期内添加两个双精度数,因此显然即使您可以更快地添加两个浮点数,它仍然会消耗 1 个周期。在旧的Intel x87 中,内部寄存器的长度为 80 位,单精度和双精度都必须扩展到 80 位,因此它们的性能也将相同。没有办法在比 80 位扩展更窄的类型中进行数学运算
使用像 SSE2/AVX/AVX-512 这样的 SIMD support,您将能够一次处理 2/4/8 个双精度数(在其他 SIMD ISA 中甚至更多),所以您可以看出,像这样添加两个双精度对象对于现代 FPU 来说只是一个小任务。但是,使用 SIMD,我们可以在寄存器中容纳两倍于双倍的浮点数,因此如果您需要并行执行大量数学运算,浮点运算会更快。在一个循环中,如果你一次可以做 4 个双打,那么你就可以在 8 个花车上做同样的事情
float 比 double 更快的另一种情况是在处理一个巨大的数组时,因为在同一缓存行中容纳的浮点数比双倍多。因此,当您遍历数组时,使用 double 会导致更多的缓存未命中
【讨论】:
“64 位机器”是一个模棱两可的术语,但通常意味着处理器的通用寄存器是 64 位宽的。比较 8086 和 8088,它们具有相同的指令集,并且都可以称为 16 位处理器在这个意义上。
当这个词组在这个意义上使用时,它与内存总线的宽度、CPU 内部的内部总线的宽度以及 ALU 在 32- 或 64- 上高效运行的能力无关位宽数据。
您的问题还假设乘法中最困难的部分是将操作数移动到处理器内部处理乘法的单元,即使操作数来自内存并且总线是 32- 这也不是完全正确的有点宽,因为延迟!=吞吐量。此外,关于浮点乘法的数学,64 位乘法的难度不是 32 位乘法的两倍,它大约是 (53/24)2 倍的难度(但是,同样,无论通用寄存器的宽度如何,晶体管都可以有效地计算双精度乘法)。
【讨论】: