我做了一些时间测试,也喜欢读一些文章,这样一个(最后的评论),它看起来像在发布版本,float和double值采取的处理时间相同.
这怎么可能?当float值与double值相比精度更低且更小时,CLR如何在相同的处理时间内获得双倍?
在x86处理器,至少,float
并且double
将每一个都可以由FPU进行处理转换成一个10字节的真实.FPU没有针对它支持的不同浮点类型的单独处理单元.
这个古老的建议float
比double
100年前大多数CPU没有内置FPU(很少有人有单独的FPU芯片)的应用速度快,因此大多数浮点操作都是在软件中完成的.在这些机器上(这是由通过熔岩凹坑产生的蒸汽驱动的),它是更快地使用float
秒.现在唯一真正的好处float
是它们占用的空间更少(只有你拥有数百万的空间才有意义).
我有一个小项目,我使用CUDA,我记得浮动速度比那里快一倍.一旦主机和设备之间的流量较低(主机是CPU和"正常"RAM,设备是GPU和相应的RAM).但即使数据一直驻留在设备上,它也会变慢.我想我在某个地方看到这个已经改变了,或者应该改变下一代,但我不确定.
所以看起来GPU在这些情况下根本无法原生地处理双精度,这也解释了为什么通常使用GLFloat而不是GLDouble.
(正如我所说的那样,只有我记得,只是在CPU上寻找浮动与双重时偶然发现了这一点.)
它取决于32位或64位系统.如果编译为64位,则double会更快.在64位(机器和操作系统)上编译为32位,浮动速度提高了约30%:
public static void doubleTest(int loop) { Console.Write("double: "); for (int i = 0; i < loop; i++) { double a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024; a = Math.Sin(a); b = Math.Asin(b); c = Math.Sqrt(c); d = d + d - d + d; e = e * e + e * e; f = f / f / f / f / f; } } public static void floatTest(int loop) { Console.Write("float: "); for (int i = 0; i < loop; i++) { float a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024; a = (float) Math.Sin(a); b = (float) Math.Asin(b); c = (float) Math.Sqrt(c); d = d + d - d + d; e = e * e + e * e; f = f / f / f / f / f; } } static void Main(string[] args) { DateTime time = DateTime.Now; doubleTest(5 * 1000000); Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds); time = DateTime.Now; floatTest(5 * 1000000); Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds); Thread.Sleep(5000); }
仍然有一些情况下浮点数是首选的 - 例如,使用OpenGL编码,使用GLFloat数据类型(通常直接映射到16位浮点数)更为常见,因为它在大多数GPU上比GLDouble更有效.