浮动与双重表现

时间:2009-01-06 18:09:06

标签: c# .net clr performance

我做了一些时序测试,并且还阅读了一些文章,如this one(最后评论),看起来在Release版本中,float和double值需要相同的处理时间。

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

4 个答案:

答案 0 :(得分:145)

在x86处理器上,至少,floatdouble将由FPU转换为10字节实数进行处理。 FPU没有针对它支持的不同浮点类型的单独处理单元。

100年前float比大多数CPU没有内置FPU(并且很少有人拥有单独的FPU芯片)所应用的double快于float的古老建议,所以大多数浮动点操作在软件中完成。在这些机器上(由熔岩坑产生的蒸汽驱动),使用float 更快。现在{{1}}唯一真正的好处是它们占用的空间更少(只有你有数百万的空间才有用)。

答案 1 :(得分:14)

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

因此,在这些情况下,GPU似乎无法原生地处理双精度,这也解释了为什么通常使用GLFloat而不是GLDouble。

(正如我所说的那样,只有我记得的时候,在CPU上搜索float与double时偶然发现了这一点。)

答案 2 :(得分:13)

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

答案 3 :(得分:11)

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