C# 浮动与双倍性能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/417568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:37:14  来源:igfitidea点击:

Float vs Double Performance

c#.netclrperformance

提问by Joan Venge

I did some timing tests and also read some articles like this one(last comment), and it looks like in Release build, float and double values take the same amount of processing time.

我做了一些计时测试,还阅读了一些像这样的文章(最后一条评论),看起来在 Release 版本中,float 和 double 值需要相同的处理时间。

How is this possible? When float is less precise and smaller compared to double values, how can the CLR get doubles into the same processing time?

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

采纳答案by P Daddy

On x86 processors, at least, floatand doublewill each be converted to a 10-byte real by the FPU for processing. The FPU doesn't have separate processing units for the different floating-point types it supports.

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

The age-old advice that floatis faster than doubleapplied 100 years ago when most CPUs didn't have built-in FPUs (and few people had separate FPU chips), so most floating-point manipulation was done in software. On these machines (which were powered by steam generated by the lava pits), it wasfaster to use floats. Now the only real benefit to floats is that they take up less space (which only matters if you have millions of them).

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

回答by Cruachan

There are still some cases where floats are preferred however - with OpenGL coding for example it's far more common to use the GLFloat datatype (generally mapped directly to 16 bit float) as it is more efficient on most GPUs than GLDouble.

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

回答by Mene

I had a small project where I used CUDA and I can remember that float was faster than double there, too. For once the traffic between Host and Device is lower (Host is the CPU and the "normal" RAM and Device is the GPU and the corresponding RAM there). But even if the data resides on the Device all the time it's slower. I think I read somewhere that this has changed recently or is supposed to change with the next generation, but I'm not sure.

我有一个使用 CUDA 的小项目,我记得浮点数在那里也比两倍快。这一次,主机和设备之间的流量较低(主机是 CPU 和“正常”RAM,设备是 GPU 和相应的 RAM)。但即使数据一直驻留在设备上,它也会变慢。我想我在某处读到这最近发生了变化或应该随着下一代而改变,但我不确定。

So it seems that the GPU simply can't handle double precision natively in those cases, which would also explain why GLFloat is usually used rather than GLDouble.

因此,在这些情况下,GPU 似乎根本无法在本机处理双精度,这也可以解释为什么通常使用 GLFloat 而不是 GLDouble。

(As I said it's only as far as I can remember, just stumbled upon this while searching for float vs. double on a CPU.)

(正如我所说,这只是我记得的,只是在 CPU 上搜索 float 与 double 时偶然发现的。)

回答by Bitterblue

It depends on 32-bitor 64-bitsystem. If you compile to 64-bit, double will be faster. Compiled to 32-bit on 64-bit (machine and OS) made float around 30% faster:

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