Drijven versus dubbele prestaties

Ik heb wat timingtests gedaan en ook enkele artikelen gelezen, zoals deze(laatste opmerking), en het lijkt erop dat in Release build, float en dubbele waarden dezelfde hoeveelheid verwerkingstijd in beslag nemen.

Hoe is dit mogelijk? Wanneer float minder nauwkeurig en kleiner is in vergelijking met dubbele waarden, hoe kan de CLR dan dubbele waarden krijgen in dezelfde verwerkingstijd?


Antwoord 1, autoriteit 100%

Op x86-processors worden floaten doublein ieder geval elk door de FPU geconverteerd naar een real van 10 bytes voor verwerking. De FPU heeft geen aparte verwerkingseenheden voor de verschillende drijvende-kommatypes die het ondersteunt.

Het eeuwenoude advies dat floatsneller is dan double, werd 100 jaar geleden toegepast toen de meeste CPU’s geen ingebouwde FPU’s hadden (en weinig mensen hadden aparte FPU’s) chips), dus de meeste manipulatie met drijvende komma werd in software gedaan. Op deze machines (die werden aangedreven door stoom die werd gegenereerd door de lavaputten), was het wassneller om floats te gebruiken. Het enige echte voordeel van floats is dat ze minder ruimte innemen (wat alleen uitmaakt als je er miljoenen hebt).


Antwoord 2, autoriteit 9%

Het hangt af van het 32-bitsof 64-bitssysteem. Als je naar 64-bit compileert, is dubbel sneller. Gecompileerd naar 32-bit op 64-bit (machine en besturingssysteem) zweefde ongeveer 30% sneller:

   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);
    }

Antwoord 3, autoriteit 8%

Ik had een klein project waarbij ik CUDA gebruikte en ik kan me herinneren dat float daar ook sneller was dan het dubbele. Voor een keer is het verkeer tussen host en apparaat lager (host is de CPU en het “normale” RAM-geheugen en apparaat is de GPU en het bijbehorende RAM-geheugen daar). Maar zelfs als de gegevens de hele tijd op het apparaat staan, is het langzamer. Ik meen ergens gelezen te hebben dat dit onlangs is veranderd of zou moeten veranderen met de volgende generatie, maar ik weet het niet zeker.

Het lijkt er dus op dat de GPU in die gevallen eenvoudigweg niet overweg kan met dubbele precisie, wat ook zou verklaren waarom GLLoat meestal wordt gebruikt in plaats van GLDouble.

(Zoals ik al zei, het is alleen voor zover ik me kan herinneren, kwam dit net tegen tijdens het zoeken naar float vs. double op een CPU.)


Antwoord 4, autoriteit 7%

Er zijn echter nog steeds gevallen waarin floats de voorkeur hebben – met OpenGL-codering is het bijvoorbeeld veel gebruikelijker om het GLFloat-datatype te gebruiken (over het algemeen direct toegewezen aan 16 bit float) omdat het efficiënter is op de meeste GPU’s dan GLDouble.

p>

Other episodes