Java光线追踪中的float与double比较

12
上学期我们在学校上课时需要开发一个光线追踪器。学校结束后,我想对它进行一些调整。我想知道如果将所有的浮点运算从双精度更改为单精度(因为计算都是用双精度完成的),那么会有什么变化。所以我将每个变量都更改为float类型,并简单地将从Math方法返回的每个double强制转换为float。在几个场景下测试我的光线追踪器,发现性能有相当大的提升。
在网上搜寻后,我发现了各种关于float可能更快的原因,但也有一些说64位环境中double可能更快甚至一样快的说法。问题是,我正在64位环境和JVM中运行程序,这种性能提升的原因是什么呢?
我正在阅读《PBRT》一书,并计划完全重写一个光线追踪器。选择在浮点运算中使用float会不会带来问题?在我的测试中没有注意到任何问题,但对于某些场景而言,较低的精度可能会带来问题(例如交点测试)。或者有一种权衡方法,即在关键测试中使用double,在次要计算中使用float?如果我决定使用float,将必须使用其他数学库来消除强制转换。

3
对于Java来说,似乎没有真正区分32位和64位编译的区别?但我在64位Java虚拟机上运行它。 - Koekje
@hagrawal 我觉得这很困难,我需要大幅简化跟踪器吗? - Koekje
@Koekje 我不知道32位和64位Javac的字节码之间是否有任何区别。很可能没有区别,只有当JVM将字节码转换为机器码并执行时才会出现差异。这确实是一个值得探究的Java领域。 - Code-Apprentice
@Code-Apprentice 减去编译器部分。在Java中,不存在32/64位编译器,也不存在32/64位类文件格式。 - biziclop
显示剩余6条评论
2个回答

9

在涉及到台式机处理器的情况下,计算速度方面,float和double之间几乎没有区别。唯一的区别在于doubles需要两倍的存储空间,因此会增加内存带宽需求。

对于基于GPU的计算来说情况就不同了,这些计算更加适合使用float。例如,Nvidia GPU的双精度性能会明显降低。

我建议采用混合方法:像多边形这样的数据可以使用float保存,但所有计算都使用double进行。这样既可以占用较小的内存空间,又可以获得高精度的计算结果,两全其美。


2
我回答得很晚,可能对你来说已经无关紧要了,但对其他人可能有所帮助。我也正在使用《PBR》一书作为个人项目编写Go语言的光线跟踪器,并且遇到了同样的问题:选择32位还是64位浮点数。我认为我会选择32位主要是出于一个原因:SIMD化光线-三角形相交测试。无论您的处理器可以使用哪个指令集(例如SSE4、AVX2、AVX512),它都可以执行每条指令的两倍32位fp运算量而不是64位。"Original Answer"翻译成"最初的回答"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接