双或浮动,这是更快?

我正在阅读“加速C ++”。 我发现一句话说“有时候执行速度比在C ++中执行速度快double ”。 读完这句话后,我对floatdouble工作感到困惑。 请向我解释这一点。

取决于本机硬件的function。

  • 如果硬件实现了双倍的function(比如x86),那么通过扩展它来模拟float,并且转换将花费时间。 在这种情况下,双倍会更快。

  • 如果硬件只实现浮点运算,那么用它来仿真会花费更多的时间。 在这种情况下,浮动会更快。

  • 如果硬件既不实现,也必须用软件来实现。 在这种情况下,两者都会很慢,但是双倍会稍微慢一些(更多的负载和存储操作)。

您提到的引用可能是指第一个案例给出的x86平台。 但这通常不成立。

你可以在这篇文章中find完整的答案

计算机科学家应该知道什么是浮点运算

这是一个前面关于内存带宽float x double的堆栈溢出线程的引用

如果double需要比float更多的存储空间,那么读取数据需要更长的时间。 这是天真的答案。 在现代IA32上,这一切都取决于数据来自何处。 如果它在L1高速caching中,只要数据来自单个高速caching行,则负载可以忽略不计。 如果它跨越多个caching行,则会有小的开销。 如果它来自L2,则需要一段时间,如果它在RAM中,那么它会更长,最后,如果它在磁盘上,这是一个很长的时间。 所以float或者double的select不如数据的使用方式重要。 如果你想对大量的连续数据做一个小的计算,那么一个小的数据types是最好的。 在一个小的数据集上做大量的计算可以让你使用更大的数据types,并且有很大的作用。 如果您非常随机地访问数据,那么select数据大小并不重要 – 数据将以页面/caching行加载。 所以即使你只需要一个RAM中的字节,也可以传输32个字节(这非常依赖于系统的体系结构)。 除此之外,CPU / FPU可以是超标量(又称stream水线)。 因此,即使负载可能需要几个周期,CPU / FPU也可能忙于做其他事情(例如乘法),从而将加载时间隐藏到一定程度

简短的回答是: 这取决于

带有x87的CPU将同样快速地收缩浮动和加倍。 向量化的代码将运行更快,因为SSE可以一次传递4个花车或2个双打。

另外要考虑的是内存速度。 根据你的algorithm,你的CPU在等待数据的时候可能会空转很多。 内存密集的代码将受益于使用浮动,但ALU有限的代码不会(除非它是vector化的)。

在英特尔,协处理器(现在整合在一起)可以同样快速地处理,但正如其他一些人所指出的那样,双倍带来更高的内存带宽,这可能会造成瓶颈。 如果您正在使用标量SSE指令(64位上的大多数编译器的默认值),则同样适用。 所以一般来说,除非你正在处理大量的数据,否则不重要。

然而,并行的SSE指令将允许在一条指令中处理四个浮点数,但是只有两个浮点数,所以这里浮点数可以明显更快。

当双打比花车更快时,我可以想到两个基本情况:

  1. 您的硬件支持双操作,但不支持浮动操作,所以浮点数将由软件模拟,因此速度较慢。

  2. 你真的需要双打的精度。 现在,如果你使用浮动,你将不得不使用两个浮动达到类似的精度加倍。 一个真正的双浮点数模拟会比首先使用浮点数慢。

    1. 你不一定需要双打,但是由于双精度的提高,你的数字algorithm会更快地收敛。 此外,双打可能提供足够的精度来使用更快但数字上不太稳定的algorithm。

为了完整起见,我也给出了一些相反的情况下花车更快的原因。 你可以看到你自己的理由是什么原因:

  1. 当你不需要双倍的精度时,浮点数比双精度要快,而且你的内存带宽是有界限的,而且你的硬件没有在浮点数上加罚值。

  2. 它们节省了内存带宽,因为它占用了每个数字一半的空间。

  3. 也有平台可以处理更多的花车比双打平行。

只有一个原因,32位浮点数可能比64位双精度(或80位80×87)慢。 这就是alignment。 除此之外,浮动内存较less,通常意味着访问速度更快,caching性能更好。 处理32位指令也需要较less的周期。 即使(共)处理器没有32位指令,也可以在64位寄存器上以相同的速度执行它们。 可能创build一个testing用例,其中双打比浮动快,vv,但我的真实统计algorithm的测量并没有显示出明显的差异。

在20亿次加3.3的实验中,结果是:

 Summation time in s: 2.82 summed value: 6.71089e+07 // float Summation time in s: 2.78585 summed value: 6.6e+09 // double Summation time in s: 2.76812 summed value: 6.6e+09 // long double 

所以double在C和C ++中更快,默认。 它在所有C和C ++库函数中更具可移植性和默认性。 阿洛斯双重比浮动显着更高的精度。

即使Stroustrupbuild议双重浮动:

“单精度,双精度和扩展精度的确切含义是由实现定义的,如果select问题需要对浮点计算有重大的理解,select正确的精度如果你没有这个理解,build议,花点时间学习,或者用双重的希望,最好的。“

也许唯一的情况,你应该使用浮动而不是双重在64位硬件与现代gcc。 因为浮动较小; double是8个字节,float是4个字节。

浮动通常更快。 双提供更高的精度。 但是,如果使用诸如3dNow或SSE之类的特殊处理器扩展,某些情况下的性能可能会有所不同。