【问题标题】:Float or Double?浮动还是双倍?
【发布时间】:2011-09-08 02:44:42
【问题描述】:

在执行算术运算 (+-*/%) 时,双倍或浮点哪个更快,出于内存原因仅使用浮点是否值得?精度不是大问题。

即使这么想,也可以说我疯了。只是好奇,因为我看到我使用的浮点数越来越大。

编辑 1: 这是在android下的唯一原因是因为我认为记忆很重要。我什至不会要求桌面开发。

【问题讨论】:

  • CPU 在处理任何一个时都非常糟糕,但整数会是理想的。您是否有计划使用浮点数或双精度数的示例?
  • 我在单位转换中使用它们(即 Torr 到 PSI 或 PSI 到 Pascal)虽然精度不是一个大问题,但如果我使用整数,我该死的和所有人说再见准确性。
  • 什么处理器?两者在模拟器上可能具有相同的“速度”,尽管它在很大程度上取决于您构建应用程序的方式。
  • @AedonEtLIRA,Whirlwin:他可能在谈论使用整数来实现自定义定点数学,这将允许您完全控制您的准确性。
  • 你有几个? 10 将节省 40 个字节。其中 10,000 个将节省 40,000 个字节。在性能方面,我不确定Android,但在x86上我相信这台机器在双打上工作最快乐。

标签: android performance memory floating-point


【解决方案1】:

在当今的 CPU 中,这两种类型的处理速度应该大致相同。

“使用所需的精度以获得可接受的结果。”

相关问题已在 SOhere is one 上被问过几次。

编辑:

在速度方面,float 和 double 在更现代的硬件上没有区别。

请查看来自 developer.android.com 的 article

【讨论】:

    【解决方案2】:

    由于从 Froyo 开始(API 8 及更高版本)在 Dalvik 中进行了 JIT(及时)优化,ADT v21 lint 消息建议使用 Double 而不是 Float。

    我使用的是 FloatMath.sin,它建议 Math.sin 在“解释问题”上下文菜单下使用以下内容。在我看来,它就像一条与双精度和浮点数相关的一般信息,而不仅仅是与三角相关的信息。

    "在旧版本的 Android 中,使用 android.util.FloatMath 被推荐用于 在浮动上操作时的性能原因。 然而,在现代硬件上,双打同样快 作为浮点数(尽管它们占用更多内存),并且在 最新版本的 Android,FloatMath 实际上是 由于 JIT 的方式,比使用 java.lang.Math 慢 优化 java.lang.Math。因此,您应该使用 如果您仅定位,则使用 Math 而不是 FloatMath Froyo 及以上。”

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      我不建议快速操作,但我相信浮点操作会更快,因为它们是 32 位与双精度中的 64 位。

      【讨论】:

      • 我编写了过滤图形的代码。它使用了浮点数,耗时 11 秒。当我转换为使用双打时,需要 5 秒。这是在 Galaxy Note 上。
      • 在大多数现代架构中,双精度通常至少与浮点数一样快,甚至更快
      • 在现代架构中,SIMD 指令使浮点数比双精度数更快。出于同样的原因,如果精度损失可以接受,整数可能是最快的。
      【解决方案4】:

      http://developer.android.com/training/articles/perf-tips.html#AvoidFloat

      避免使用浮点数

      根据经验,浮点数比整数慢约 2 倍 Android 设备。

      在速度方面,float 和 double 没有区别 更现代的硬件。在空间方面,双倍大 2 倍。与台式机一样 机器,假设空间不是问题,你应该更喜欢双 浮动。

      此外,即使是整数,一些处理器也有硬件乘法,但 缺乏硬件鸿沟。在这种情况下,整数除法和模数 操作是在软件中执行的——如果 您正在设计哈希表或做大量数学运算。

      【讨论】:

        【解决方案5】:

        浮点数是 32 位或 4 个字节

        double 是 64 位或 8 字节

        是的,根据 sun java 认证书,float 的大小只有一半。

        【讨论】:

        • 如果大部分存储最终都在 CPU 寄存器中,并且寄存器足够大,可以容纳任何一个,并且使用相同数量的指令,这意味着什么。
        • 我确定这本书并没有说它们的速度是两倍。
        • @EJP 和@Merlyn - 最诚挚的歉意。我更正了我的帖子。这本书确实说它们只有一半大小,所以在我看来,这表明效率有所提高。显然我错了。
        【解决方案6】:

        在速度方面,float 和 double 在更现代的硬件上没有区别。

        非常便宜的设备似乎具有有限的 FPU,其中 float 比 double 快。我在目前作为世界上最便宜的平板电脑之一销售的 CMX 设备上进行了测试:

        • “float”测试代码耗时 4.7 秒
        • 与“double”相同的代码需要 6.6 秒

        这个问题已经问了好几次了...

        是的。因为对于不同类型的硬件,答案是不同的。在台式计算机上,double 的速度与 float 相同。在没有 FPU(对 WLAN 路由器黑客感兴趣)的设备上,浮动速度比两倍快 2-5 倍;在具有 32 位 FPU(通常在工业和汽车应用中发现)的设备上甚至高达 100 次。

        请查看这篇文章...

        文章的最后一部分说,您必须在要使用的硬件设备上进行时间测量才能 100% 确定。

        【讨论】:

          【解决方案7】:

          引用的 android 文档表明整数更适合快速操作。从表面上看,这似乎有点奇怪,但是使用整数、浮点数和双精度数的算法的速度取决于几个层次:

          1. JIT 或 VM:它们会将数学运算转换为主机的本机指令集,并且这种转换会对性能产生很大影响。由于底层硬件可能因平台而异,因此很难编写在所有情况下都能发出最佳代码的 VM 或 JIT。最好还是使用 JIT/VM 推荐的快速类型(在本例中为整数),因为随着 JIT 和 VM 在发出更高效的本机指令方面做得更好,您的高级代码应该会获得相关的性能提升,而无需任何修改。

          2. 本机硬件(为什么第一级不完美):现在大多数处理器都有硬件浮点单元(支持浮点数和双精度)。如果存在这样的硬件单元,浮点数/双精度数可能比整数更快,除非还有硬件整数支持。使问题更加复杂的是,大多数 CPU 都具有某种形式的 SIMD(单指令多数据)支持,如果数据类型足够小,则允许对操作进行矢量化(例如,通过在每个寄存器中放入两个浮点数而不是在一个指令中添加 4 个浮点数)为 4 个双打中的每一个使用一个完整的寄存器)。这可以让使用较少位的数据类型的处理速度比双精度数据类型快得多,但会牺牲精度。

          优化速度需要详细了解这两个级别以及它们之间的交互方式。即使优化内存使用也可能很棘手,因为 VM 可能出于其他原因选择在更大的内存空间中表示您的数据:浮点数可能会占用 VM 代码中的 8 个字节,尽管这种可能性较小。所有这些都使得优化几乎成为可移植性的对立面。因此,再次强调,最好使用 VM 推荐的“快速”数据类型,因为这样可以在受支持的设备上实现最佳平均性能。

          这根本不是一个坏问题,即使在台式机上也是如此。是的,它们现在非常快,但是如果您正在实现一个复杂的算法(例如,快速傅里叶变换),即使是很小的优化也会对算法的运行时间产生巨大影响。无论如何,您的问题“哪个更快:浮动或双打”的答案是“取决于”:)

          【讨论】:

            【解决方案8】:

            我也好奇这个,写了一个小测试:

            #include <iostream>
            #include <chrono>
            
            template<typename numType>
            void test(void)  {
                std::cout<< "Size of variable: " << sizeof(numType) << std::endl;
                numType array[20000];
            
                auto t1 = std::chrono::high_resolution_clock::now();
                // fill array
                for( numType& number : array ) {
                    number = 1.0014535;
                }
            
                auto t2 = std::chrono::high_resolution_clock::now();
            
                // multiply each number with itself 10.000 times
                for( numType& number : array ) {
                    for( int i=0; i < 10000 ; i++ )  {
                        number *= number;
                    }
                }
            
                auto t3 = std::chrono::high_resolution_clock::now();
            
                auto filltime = t2 - t1;
                auto calctime = t3 - t2;
            
                std::cout<< "Fill time: " << filltime.count() << std::endl;
                std::cout<< "Calc time: " << calctime.count() << std::endl;
            }
            
            int main(int argc, char* argv[]) {
                test<float>();
                test<double>();
            }
            

            我在 Intel i7 3930k 处理器上使用 GCC 在 Ubuntu 12.04 x64 下运行和编译它

            结果如下:

            Size of variable: 4
            Fill time: 69
            Calc time: 694303
            
            Size of variable: 8
            Fill time: 76
            Calc time: 693363
            

            结果是可重复的。因此 double 的内存分配需要稍长一些,但实际计算时间完全相同。


            出于好奇,我还在 Windows 7 x64 下使用 Visual Studio 2012 在英特尔 i7 920 处理器上以发布模式运行和编译它

            (时间单位不同,请勿将以上结果与这些结果进行比较:仅对内部比较有效)

            Size of variable: 4
            Fill time: 0
            Calc time: 3200183
            
            Size of variable: 8
            Fill time: 0
            Calc time: 3890223
            

            结果是可重复的。

            windows 上的分配似乎是即时的,也许是因为 linux 在您使用它之前实际上并没有给您内存,而 windows 只是一次将它全部交给您,需要较少的系统调用。或者,分配可能被优化掉了。

            这里的双精度乘法比浮点数慢 21.5%。与之前测试的这种差异可能是由于处理器不同(至少这是我的最佳猜测)。

            【讨论】:

            • 这个基准测试很有趣,但离题了。讨论是针对 Android 的 java。尽管事后看来,这个问题还是被操纵了,因为手机上的硬件通常非常不同。 :-/
            猜你喜欢
            • 2010-12-10
            • 2011-12-12
            • 1970-01-01
            • 2019-07-10
            • 2013-05-20
            • 2010-12-22
            • 2010-09-24
            • 2013-11-21
            相关资源
            最近更新 更多