当前位置:  开发笔记 > 编程语言 > 正文

浮动与双重表现

如何解决《浮动与双重表现》经验,为你挑选了4个好方法。

我做了一些时间测试,也喜欢读一些文章,这样一个(最后的评论),它看起来像在发布版本,float和double值采取的处理时间相同.

这怎么可能?当float值与double值相比精度更低且更小时,CLR如何在相同的处理时间内获得双倍?



1> P Daddy..:

在x86处理器,至少,float并且double将每一个都可以由FPU进行处理转换成一个10字节的真实.FPU没有针对它支持的不同浮点类型的单独处理单元.

这个古老的建议floatdouble100年前大多数CPU没有内置FPU(很少有人有单独的FPU芯片)的应用速度快,因此大多数浮点操作都是在软件中完成的.在这些机器上(这是由通过熔岩凹坑产生的蒸汽驱动的),它更快地使用float秒.现在唯一真正的好处float是它们占用的空间更少(只有你拥有数百万的空间才有意义).


需要注意SIMD代码 - 因为你可以将2x浮点数打包到SIMD寄存器(例如SSE)中,所以可能会更快地对浮点数进行操作.但由于它是C#,这可能不会发生.
@P爸爸:我会说空间优势在缓存层次的各个层面都很重要.当您的第一级数据缓存大16KB并且您正在处理4000个数字的数组时,float可以更快.
也许不是100年前......有些FPU支持float,double和80-bit级别的本机处理,并且在较短的长度上执行速度更快.有些人实际上会以较短的长度执行一些更慢的事情...... :-)
@artificialidiot永远不要说永远;).从4.6开始,.NET支持SIMD
可能的例外:我认为分割的时间取决于位数(1个时钟周期/ 2位).我用漂浮与双师制作的计时似乎与此相符.
这个答案并不完全正确.80位数学比64位数学慢.64位代码总是使用64位SIMD(SSE)向量来处理数学,这就是结果更快的原因.32位数学运算将与64位同时执行.为了证明64位SSE数学运算比80位FPU数学运算更快,在Delphi中编写相同的数学运算,结果不言而喻.此外,在32位操作系统上,由于加载和存储以及有时操作,32位数学运算速度较慢.最后,32位数学可能需要1/2内存混洗(对于大型数组),因此在这种情况下自然会更快.

2> Mene..:

我有一个小项目,我使用CUDA,我记得浮动速度比那里快一倍.一旦主机和设备之间的流量较低(主机是CPU和"正常"RAM,设备是GPU和相应的RAM).但即使数据一直驻留在设备上,它也会变慢.我想我在某个地方看到这个已经改变了,或者应该改变下一代,但我不确定.

所以看起来GPU在这些情况下根本无法原生地处理双精度,这也解释了为什么通常使用GLFloat而不是GLDouble.

(正如我所说的那样,只有我记得,只是在CPU上寻找浮动与双重时偶然发现了这一点.)


GPU与FPU完全不同.正如其他人提到的那样,FPU的原生格式是80位双精度.那已经很久了.然而,GPU从单精度接近该领域.众所周知**他们的DP FP(双精度浮点)性能通常恰好是SP FP性能的一半.它们似乎经常具有SP浮点单元,并且它们必须重用该单元来覆盖双精度.与一个相比,其产生恰好两个周期.这是一个巨大的性能差异**,当我面对它时,这让我感到震惊.

3> Bitterblue..:

它取决于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);
    }


您是否考虑过那30%可能是因为您使用了额外的演员表?
上面发布的结果是虚假的。我的测试表明,在具有.NET 4.0发行版模式的旧32位计算机上,“ float”和“ double”性能实际上是相同的。在许多独立试验中取平均值时,相差不到0.3%,在这些试验中,每个试验对连续链接的变量进行乘法,除法和加法运算(以避免妨碍编译器优化)。我用`Math.Sin()`和`Math.Sqrt()`进行了第二组测试,结果也相同。

4> Cruachan..:

仍然有一些情况下浮点数是首选的 - 例如,使用OpenGL编码,使用GLFloat数据类型(通常直接映射到16位浮点数)更为常见,因为它在大多数GPU上比GLDouble更有效.


可能是由于更高的数据吞吐量?如果你有一个数字矩阵(z缓冲区等),数据大小变得更加重要,并避免浮动和双倍之间的转换加速处理.我猜.
无疑是吞吐量。同样,在特殊情况下,使用浮点数中的double值不可能获得任何可见的信息,所以为什么要浪费内存-特别是因为GPU上的内存比CPU短
推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有