简体   繁体   English

C#中的浮点数比浮点数快吗?

[英]Are doubles faster than floats in C#?

I'm writing an application which reads large arrays of floats and performs some simple operations with them. 我正在编写一个应用程序,该应用程序读取大量的float并对其执行一些简单的操作。 I'm using floats, because I thought it'd be faster than doubles, but after doing some research I've found that there's some confusion about this topic. 我使用的是float,因为我认为它比double更快,但是经过一些研究后,我发现这个主题有些混乱。 Can anyone elaborate on this? 有人可以详细说明吗?

The short answer is, "use whichever precision is required for acceptable results." 简短的答案是:“使用任何精度才能获得可接受的结果。”

Your one guarantee is that operations performed on floating point data are done in at least the highest precision member of the expression. 您的一个保证是,至少在表达式的最高精度成员中对浮点数据执行的操作。 So multiplying two float 's is done with at least the precision of float , and multiplying a float and a double would be done with at least double precision. 因此,将两个float的乘积至少以float的精度完成,将floatdouble乘以至少会以double精度完成。 The standard states that "[floating-point] operations may be performed with higher precision than the result type of the operation." 该标准指出:“ [浮点]操作可以比操作的结果类型更高的精度执行”。

Given that the JIT for .NET attempts to leave your floating point operations in the precision requested, we can take a look at documentation from Intel for speeding up our operations. 鉴于.NET的JIT试图使您的浮点运算保持所要求的精度,我们可以查看英特尔的文档,以加快运算速度。 On the Intel platform your floating point operations may be done in an intermediate precision of 80 bits, and converted down to the precision requested. 在Intel平台上,您的浮点运算可能以80位的中间精度完成,然后转换为要求的精度。

From Intel's guide to C++ Floating-point Operations 1 (sorry only have dead tree), they mention: 从Intel的C ++浮点运算指南1 (很抱歉只有死树),他们提到:

  • Use a single precision type (for example, float) unless the extra precision obtained through double or long double is required. 除非需要通过double或long double获得的额外精度,否则请使用单精度类型(例如float)。 Greater precision types increase memory size and bandwidth requirements. 精度更高的类型会增加内存大小和带宽要求。 ... ...
  • Avoid mixed data type arithmetic expressions 避免混合数据类型的算术表达式

That last point is important as you can slow yourself down with unnecessary casts to/from float and double , which result in JIT'd code which requests the x87 to cast away from its 80-bit intermediate format in between operations! 最后一点很重要,因为您可以使用不必要的对float和double的强制转换来放慢自己的速度 ,这会导致JIT代码,从而要求x87在两次操作之间转换其80位中间格式!

1. Yes, it says C++, but the C# standard plus knowledge of the CLR lets us know the information for C++ should be applicable in this instance. 1.是的,它说的是C ++,但是C#标准以及CLR的知识使我们知道C ++的信息应在这种情况下适用。

I just read the "Microsoft .NET Framework-Application Development Foundation 2nd" for the MCTS exam 70-536 and there is a note on page 4 (chapter 1): 我刚刚阅读了MCTS考试70-536的“ Microsoft .NET Framework-应用程序开发基础2nd”,并且在第4页(第1章)上有一条注释:

NOTE Optimizing performance with built-in types 注意使用内置类型优化性能
The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables. 运行时优化了32位整数类型(Int32和UInt32)的性能,因此请将这些类型用于计数器和其他经常访问的整数变量。 For floating-point operations, Double is the most efficient type because those operations are optimized by hardware. 对于浮点运算,Double是最有效的类型,因为这些运算是由硬件优化的。

It's written by Tony Northrup. 它是由Tony Northrup撰写的。 I don't know if he's an authority or not, but I would expect that the official book for the .NET exam should carry some weight. 我不知道他是否是权威人士,但是我希望.NET考试的官方书应能有所帮助。 It is of course not a gaurantee. 当然不是保证金。 I just thought I'd add it to this discussion. 我只是想将其添加到此讨论中。

I profiled a similar question a few weeks ago. 几周前,我提出了一个类似的问题。 The bottom line is that for x86 hardware, there is no significant difference in the performance of floats versus doubles unless you become memory bound, or you start running into cache issue. 最重要的是,对于x86硬件,除非变为内存受限或开始遇到缓存问题,否则浮点数和双倍数的性能没有显着差异。 In that case floats will generally have the advantage because they are smaller. 在这种情况下,浮子通常会具有优势,因为它们较小。

Current Intel CPUs perform all floating point operations in 80 bit wide registers so the actual speed of the computation shouldn't vary between floats and doubles. 当前的Intel CPU在80位宽的寄存器中执行所有浮点运算,因此实际的运算速度不应在浮点数和双精度数之间变化。

I'm writing a ray tracer, and replacing the floats with doubles for my Color class gives me a 5% speedup. 我正在编写一个光线跟踪器,并将Color类的浮点数替换为double值会使我的速度提高5%。 Replacing the Vectors floats with doubles is another 5% faster! 用double替换Vector浮点又快了5%! Pretty cool :) 太酷了:)

That's with a Core i7 920 配备酷睿i7 920

If load & store operations are the bottleneck, then floats will be faster, because they're smaller. 如果加载和存储操作成为瓶颈,那么浮点数会更快,因为它们较小。 If you're doing a significant number of calculations between loads and stores, it should be about equal. 如果要在装载和存储之间进行大量计算,则计算应该大致相等。

Someone else mentioned avoiding conversions between float & double, and calculations that use operands of both types. 有人提到避免在float和double之间进行转换,以及避免使用两种类型的操作数进行计算。 That's good advice, and if you use any math library functions that return doubles (for example), then keeping everything as doubles will be faster. 这是一个很好的建议,如果您使用任何返回双精度数的数学库函数(例如),则将所有内容都保持为双精度会更快。

With 387 FPU arithmetic, float is only faster than double for certain long iterative operations like pow, log, etc (and only if the compiler sets the FPU control word appropriately). 使用387 FPU算法,对于某些较长的迭代操作(例如pow,log等)(且仅在编译器适当地设置了FPU控制字的情况下),float仅比双倍快。

With packed SSE arithmetic, it makes a big difference though. 使用打包的SSE算法,尽管有很大的不同。

Matthijs, Matthijs,

You are wrong. 你错了。 32-bit is far more efficient than 16-bit - in modern processors... Perhaps not memory-wise, but in effectiveness 32-bit is the way to go. 在现代处理器中,32位比16位的效率要高得多。也许不是内存方面的,但实际上32位是有效的方法。

You really should update your professor to something more "up-to-date". 您确实应该将您的教授更新为更多“最新”的东西。 ;) ;)

Anyway, to answer the question; 无论如何,要回答这个问题; float and double has exactly the same performance, at least on my Intel i7 870 (as in theory). float和double具有完全相同的性能,至少在我的Intel i7 870上(理论上)。

Here are my measurements: 这是我的尺寸:

(I made an "algorithm" that I repeated for 10,000,000 times, and then repeated that for 300 times, and out of that I made a average.) (我做了一个“算法”,我重复了1000万次,然后又重复了300次,然后我算出了平均值。)

double
-----------------------------
1 core  = 990 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms

float
-----------------------------
1 core  = 992 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms

This indicates that floats are slightly faster than doubles: http://www.herongyang.com/cs_b/performance.html 这表明浮点数比双精度点快一点: http : //www.herongyang.com/cs_b/performance.html

In general, any time you do a comparison on performance, you should take into account any special cases, like does using one type require additional conversions or data massaging? 通常,在进行性能比较时,应考虑任何特殊情况,例如使用一种类型是否需要额外的转换或数据按摩? Those add up and can belie generic benchmarks like this. 这些加起来并可以掩盖像这样的通用基准。

在32位系统上,浮点数应该更快,但是要分析代码以确保您在优化正确的东西。

I have always thought that the processors were optimized or the same regardless of float or double. 我一直认为处理器是优化的还是相同的,而不管float还是double。 Searching for optimizations on my intensive computations (lots of gets from a matrix, comparisons of two values) I found out that floats run about 13% faster. 在密集计算中搜索优化(从矩阵中获取大量数据,比较两个值),我发现浮点数的运行速度提高了约13%。

This surprised me, but I guess it is due to the nature of my problem. 这让我感到惊讶,但是我想这是由于我的问题的性质所致。 I don't do casts between float and double in the core of the operations, and my computations are mainly adding, multiplying and subtracting. 在运算的核心中,我不进行浮点数和双精度之间的强制转换,而我的计算主要是加,乘和减。

This is on my i7 920, running a 64-bit operating system. 这是在运行64位操作系统的i7 920上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM