C++ 双人还是浮动,哪个更快?
我正在读《加速C++》。我发现有一句话说“有时C++ 双人还是浮动,哪个更快?,c++,floating-point,double,C++,Floating Point,Double,我正在读《加速C++》。我发现有一句话说“有时double比C++中的float执行得更快”。读了这个句子后,我对float和double工作感到困惑。请给我解释一下这一点 您可以在本文中找到完整的答案: 这是对上一个堆栈溢出线程的引用,关于float和double变量如何影响内存带宽: 如果双人间需要 比浮点数更多的存储空间,那么 读取数据将花费更长的时间。 这是天真的回答。论现代社会 IA32,这完全取决于数据的位置 是从哪里来的。如果它在一级缓存中, 如果 数据来自单个缓存线。 如果它跨
double
比C++中的float
执行得更快”。读了这个句子后,我对float
和double
工作感到困惑。请给我解释一下这一点 您可以在本文中找到完整的答案:
这是对上一个堆栈溢出线程的引用,关于float
和double
变量如何影响内存带宽:
如果双人间需要
比浮点数更多的存储空间,那么
读取数据将花费更长的时间。
这是天真的回答。论现代社会
IA32,这完全取决于数据的位置
是从哪里来的。如果它在一级缓存中,
如果
数据来自单个缓存线。
如果它跨越多个缓存线
头顶上有一个小洞。如果是从
L2,如果它是
在RAM中,它会变得更长、更稳定
最后,如果它在磁盘上,它是一个巨大的
时间所以选择浮动还是双精度
比数据的方式更重要
使用。如果你想做一个小游戏
大量连续数据的计算
数据,最好是小数据类型。
在小型计算机上进行大量计算
数据集将允许您使用更大的
具有任何重要属性的数据类型
效果。如果你正在访问数据
非常随机,然后选择数据
大小不重要-数据已加载
在页/缓存行中。所以即使你
只需要RAM中的一个字节,就可以了
传输32字节(这是非常重要的
取决于
系统)。最重要的是
CPU/FPU可以是超标量(也称为
管道)。因此,即使可能会出现负载
需要几个周期,CPU/FPU可以
忙于做别的事情
(例如,乘法)隐藏
加载时间达到一定程度
我可以想到两种基本情况,即双倍比浮点数快:
浮动通常更快。双精度提供更高的精度。但是,如果使用3dNow或SSE等特殊处理器扩展,在某些情况下性能可能会有所不同。取决于本机硬件的功能
- 如果硬件是(或类似于)具有传统x87数学的x86,则float和double都将(免费)扩展为内部80位格式,因此它们都具有相同的性能(缓存占用空间/内存带宽除外)
- 如果硬件以本机方式实现这两种操作,如大多数现代ISA(包括x86-64,其中SSE2是标量FP数学的默认值),则通常大多数FPU操作的速度都相同,当然也比乘法或加法慢得多。(浮点值越小,缓存未命中的次数就越少。对于SIMD,对于向量化的循环,每个向量的元素数是原来的两倍)
- 如果硬件只实现了double,那么如果在float load和float store指令中不能自由地进行与本机double格式的转换,则float的速度会变慢
- 如果硬件只实现float,那么使用它模拟double将花费更多的时间。在这种情况下,float将更快
- 如果硬件两者都没有实现,那么两者都必须在软件中实现。在这种情况下,两者都会很慢,但double会稍微慢一点(至少会有更多的加载和存储操作)
3.3f
来避免它,让你的编译器生成高效的asm,如果你想要的话,它可以将数字保持为浮点数。在英特尔上,协处理器(现在集成的)将以同样快的速度处理这两个问题,但正如其他一些人所指出的,加倍会导致更高的内存带宽,这可能会导致瓶颈。如果您使用的是标量SSE指令(大多数64位编译器的默认指令),同样适用。因此,一般来说,除非您处理的是大量数据,否则这并不重要
然而,并行SSE指令将允许在一条指令中处理四个浮点,但只有两个浮点,因此这里的浮点可以明显更快。简短的回答是:这取决于 使用x87的CPU将以同样快的速度处理浮动和加倍。矢量化代码在使用浮点运算时会运行得更快,因为SSE可以在一次运算中处理4个浮点运算或2个双倍运算 另一件需要考虑的是记忆速度。根据您的算法,您的CPU在等待数据时可能会大量空闲。内存密集型代码将受益于使用浮动,但ALU有限型代码不会(除非它是矢量化的)。
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