对Float vs Double基准感到困惑

时间:2019-08-17 01:57:27

标签: c# .net windows floating-point benchmarking

在SO中搜索.NET中浮点和双精度之间的性能差异之后,我整理了一个简单的基准测试了2种方法,每种方法都具有浮点和双精度,调试和释放。几次运行基准测试之后,我对x64发行版中Func2Double和Func2Float方法中float和double的计时结果感到困惑。 Func2Double的行为(缓慢的基准测试时间)就像是调试版本一样。其他方法(Func1Double,Func1Float,Func2Float)都产生了比调试方法更快的基准时间(按预期)。我对x64发行版的float版本和double版本的IL进行了比较,但是没有发现任何明显的差异可以解释我得到的结果。

有人能在BenchmarkFloatVsDouble-x64-release.exe中解释Func2Double的基准测试结果如何吗?

这是我测试过的源代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace BenchmarkFloatVsDouble
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("OSDescription: {0}", RuntimeInformation.OSDescription);
            Console.WriteLine("OSArchitecture: {0}", RuntimeInformation.OSArchitecture);
            Console.WriteLine("ProcessArchitecture: {0}", RuntimeInformation.ProcessArchitecture);
            Console.WriteLine("FrameworkDescription: {0}", RuntimeInformation.FrameworkDescription);

            Console.WriteLine();

            var ev = Environment.GetEnvironmentVariables();
            Console.WriteLine("PROCESSOR_ARCHITEW6432: {0}", ev["PROCESSOR_ARCHITEW6432"]);
            Console.WriteLine("PROCESSOR_ARCHITECTURE: {0}", ev["PROCESSOR_ARCHITECTURE"]);
            Console.WriteLine("PROCESSOR_IDENTIFIER: {0}", ev["PROCESSOR_IDENTIFIER"]);
            Console.WriteLine("NUMBER_OF_PROCESSORS: {0}", ev["NUMBER_OF_PROCESSORS"]);

            Console.WriteLine();

            Console.WriteLine("Is64BitProcess: {0}", Environment.Is64BitProcess);
            Console.WriteLine("Is64BitOperatingSystem: {0}", Environment.Is64BitOperatingSystem);

            Console.WriteLine();

            using (var p = Process.GetCurrentProcess())
            {
                p.PriorityClass = ProcessPriorityClass.RealTime;
            }

            var template = "{0,15}, {1,15}, {2,15}, {3,15}";

            Console.WriteLine(
             template,
             "Func1Double",
             "Func1Float",
             "Func2Double",
             "Func2Float");

            var count = 100 * 1000 * 1000;
            var v1 = 1.23456789D;
            var v2 = 1.23456789F;

            for (var ii = 0; ii < 10; ii++)
            {
                var t1 = Environment.TickCount;
                for (var i = 0; i < count; i++) Func1Double(v1);
                var d1 = Environment.TickCount - t1;

                var t2 = Environment.TickCount;
                for (var i = 0; i < count; i++) Func1Float(v2);
                var d2 = Environment.TickCount - t2;

                var t3 = Environment.TickCount;
                for (var i = 0; i < count; i++) Func2Double(v1);
                var d3 = Environment.TickCount - t3;

                var t4 = Environment.TickCount;
                for (var i = 0; i < count; i++) Func2Float(v2);
                var d4 = Environment.TickCount - t4;

                Console.WriteLine(template, d1, d2, d3, d4);
            }

            Console.WriteLine("Done");
            Console.ReadKey();
        }

        public static double Func1Double(double x)
        {
            return Math.Exp(-x * x);
        }

        public static float Func1Float(float x)
        {
            return (float)Math.Exp(-x * x);
        }

        public static double Func2Double(double x)
        {
            return 1d - (1d / (1d + (x * x)));
        }

        public static float Func2Float(float x)
        {
            return 1f - (1f / (1f + (x * x)));
        }
    }
}

这是我创建可执行文件的方式。我知道我可以在VS中完成4个版本(x86 / x64 x调试/发行版)的批处理构建,但是我希望能够在此处显示所有步骤。我对.NET 4附带的csc.exe进行了相同的测试,但是得到了相同的结果。

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>csc /platform:x64 /optimize- /debug+ /debug:full /define:DEBUG;TRACE /out:BenchmarkFloatVsDouble-x64-debug.exe Program.cs

Microsoft (R) Visual C# Compiler version 3.2.0-beta4-19380-04 (5e176ad8)
Copyright (C) Microsoft Corporation. All rights reserved.


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>csc /platform:x64 /optimize+ /debug- /debug:pdbonly /define:TRACE /out:BenchmarkFloatVsDouble-x64-release.exe Program.cs

Microsoft (R) Visual C# Compiler version 3.2.0-beta4-19380-04 (5e176ad8)
Copyright (C) Microsoft Corporation. All rights reserved.


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>csc /platform:x86 /optimize- /debug+ /debug:full /define:DEBUG;TRACE /out:BenchmarkFloatVsDouble-x86-debug.exe Program.cs

Microsoft (R) Visual C# Compiler version 3.2.0-beta4-19380-04 (5e176ad8)
Copyright (C) Microsoft Corporation. All rights reserved.


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>csc /platform:x86 /optimize+ /debug- /debug:pdbonly /define:TRACE /out:BenchmarkFloatVsDouble-x86-release.exe Program.cs

Microsoft (R) Visual C# Compiler version 3.2.0-beta4-19380-04 (5e176ad8)
Copyright (C) Microsoft Corporation. All rights reserved.

这是运行4个不同版本的结果。

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>BenchmarkFloatVsDouble-x64-release.exe

OSDescription: Microsoft Windows 10.0.16299
OSArchitecture: X64
ProcessArchitecture: X64
FrameworkDescription: .NET Framework 4.7.3416.0

PROCESSOR_ARCHITEW6432:
PROCESSOR_ARCHITECTURE: AMD64
PROCESSOR_IDENTIFIER: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
NUMBER_OF_PROCESSORS: 8

Is64BitProcess: True
Is64BitOperatingSystem: True

    Func1Double,      Func1Float,     Func2Double,      Func2Float
             31,              31,             375,              32
             31,              15,             375,              32
             31,              31,             391,              31
             31,              16,             375,              31
             31,              16,             375,              31
             32,              31,             375,              15
             32,              31,             375,              16
             31,              31,             375,              16
             31,              31,             375,              16
             16,              31,             375,              32
Done


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>BenchmarkFloatVsDouble-x86-release.exe

OSDescription: Microsoft Windows 10.0.16299
OSArchitecture: X64
ProcessArchitecture: X86
FrameworkDescription: .NET Framework 4.7.3416.0

PROCESSOR_ARCHITEW6432: AMD64
PROCESSOR_ARCHITECTURE: x86
PROCESSOR_IDENTIFIER: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
NUMBER_OF_PROCESSORS: 8

Is64BitProcess: False
Is64BitOperatingSystem: True

    Func1Double,      Func1Float,     Func2Double,      Func2Float
           1219,            1203,             375,             375
           1219,            1203,             375,             375
           1219,            1203,             375,             375
           1219,            1234,             375,             375
           1219,            1219,             375,             375
           1234,            1219,             375,             375
           1218,            1219,             375,             375
           1219,            1203,             375,             375
           1219,            1219,             375,             375
           1218,            1250,             375,             375
Done


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>BenchmarkFloatVsDouble-x64-debug.exe

OSDescription: Microsoft Windows 10.0.16299
OSArchitecture: X64
ProcessArchitecture: X64
FrameworkDescription: .NET Framework 4.7.3416.0

PROCESSOR_ARCHITEW6432:
PROCESSOR_ARCHITECTURE: AMD64
PROCESSOR_IDENTIFIER: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
NUMBER_OF_PROCESSORS: 8

Is64BitProcess: True
Is64BitOperatingSystem: True

    Func1Double,      Func1Float,     Func2Double,      Func2Float
           1453,            1547,             485,             453
           1437,            1531,             454,             453
           1407,            1500,             453,             453
           1422,            1515,             453,             469
           1406,            1500,             469,             453
           1391,            1500,             453,             469
           1406,            1500,             453,             469
           1422,            1500,             453,             469
           1390,            1500,             469,             453
           1406,            1516,             469,             469
Done


D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>BenchmarkFloatVsDouble-x86-debug.exe

OSDescription: Microsoft Windows 10.0.16299
OSArchitecture: X64
ProcessArchitecture: X86
FrameworkDescription: .NET Framework 4.7.3416.0

PROCESSOR_ARCHITEW6432: AMD64
PROCESSOR_ARCHITECTURE: x86
PROCESSOR_IDENTIFIER: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
NUMBER_OF_PROCESSORS: 8

Is64BitProcess: False
Is64BitOperatingSystem: True

    Func1Double,      Func1Float,     Func2Double,      Func2Float
           1719,            1672,             484,             469
           1719,            1687,             484,             454
           1718,            1688,             484,             469
           1703,            1688,             484,             453
           1734,            1750,             500,             485
           1750,            1750,             500,             469
           1765,            1735,             500,             468
           1766,            1687,             485,             469
           1703,            1687,             485,             468
           1766,            1719,             484,             500
Done


以及用于生成IL以便更仔细检查的命令。

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>ildasm BenchmarkFloatVsDouble-x64-debug.exe /out=BenchmarkFloatVsDouble-x64-debug.exe.il

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>ildasm BenchmarkFloatVsDouble-x64-release.exe /out=BenchmarkFloatVsDouble-x64-release.exe.il

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>ildasm BenchmarkFloatVsDouble-x86-debug.exe /out=BenchmarkFloatVsDouble-x86-debug.exe.il

D:\files\dev\BenchmarkFloatVsDouble\BenchmarkFloatVsDouble>ildasm BenchmarkFloatVsDouble-x86-release.exe /out=BenchmarkFloatVsDouble-x86-release.exe.il

IL Compare

https://github.com/gregmulvihill/BenchmarkFloatVsDouble

0 个答案:

没有答案