Float - Çift Performans


92

Bazı zamanlama testler yaptı ve aynı zamanda gibi bazı makaleleri okumak bu bir (son yorum) ve Yayın yapılı, şamandıra ve çift değerler işleme zaman aynı miktarda almak gibi görünüyor.

Bu nasıl mümkün olabilir? Float çift değerlere kıyasla daha az hassas ve daha küçük olduğunda, CLR aynı işlem süresine nasıl iki katına çıkabilir?


10
Bunun tam olarak bir kopyası olduğunu sanmıyorum, çünkü bunun arkasındaki nedeni soruyor, diğer kullanıcı gerçekten daha hızlı olup olmadığını soruyor, ancak neden olması gerekmiyor
Joan Venge

Sözde, Are'nin tam bir kopyası C # 'ta kayanlardan daha hızlı çiftler mi? (2009'da başka bir kullanıcı tarafından talep edildi).
Peter Mortensen

Yanıtlar:


157

En azından x86 işlemcilerinde floatve doubleher biri işlem için FPU tarafından 10 bayta gerçek dönüştürülecektir. FPU, desteklediği farklı kayan nokta türleri için ayrı işleme birimlerine sahip değildir.

100 yıl önce çoğu CPU'nun yerleşik FPU'ları olmadığı (ve birkaç kişinin ayrı FPU yongaları olduğu) uygulanandan floatdaha hızlı olan eski tavsiye double, bu nedenle çoğu kayan nokta manipülasyonu yazılımda yapıldı. (Lav çukurları tarafından oluşturulan buhar aracılığıyla sağlanıyordu) bu makinalarda bu oldu kullanmak daha hızlı floats. Şimdi e'lerin tek gerçek yararı, floatdaha az yer kaplamalarıdır (bu, yalnızca milyonlarcasına sahipseniz önemlidir).


9
Belki 100 yıl önce değil ... Bazı FPU'lar kayan, çift ve 80 bit seviyelerde yerel işlemeyi destekler ve daha kısa uzunluklarda daha hızlı çalışır. Bazıları aslında bazı şeyleri daha kısa uzunluklarda daha yavaş yürütecek ... :-)
Brian Knoblauch

4
Olası istisna: Bölme süresinin bit sayısına bağlı olduğunu düşünüyorum (1 saat döngüsü / 2 bit). Float vs double division'dan yaptığım zamanlamalar bununla uyumlu görünüyor.
Neil Coffey

22
SIMD kodu için uyarı - SIMD yazmacına (örn. SSE) 2 kat kayan değer koyabildiğiniz için, potansiyel olarak kayan değerler üzerinde çalışmak daha hızlı olabilir. Ancak C # olduğu için bu muhtemelen olmayacak.
Calyth

14
@P Daddy: Alan avantajının önbellek hiyerarşisinin her seviyesinde önemli olduğunu söyleyebilirim. İlk düzey veri önbelleğiniz 16KB büyük olduğunda ve 4000 sayılık bir dizi çalıştırıyorsanız, float kolayca daha hızlı olabilir.
Peter G.

4
@ yapayidiot Asla asla deme;). SIMD,
4.6'dan

13

CUDA'yı kullandığım küçük bir projem vardı ve şamandıranın orada da iki katından daha hızlı olduğunu hatırlıyorum. Bir kez için Ana Bilgisayar ve Aygıt arasındaki trafik daha düşüktür (Ana Bilgisayar CPU'dur ve "normal" RAM ve Aygıt, GPU ve oradaki karşılık gelen RAM'dir). Ancak veriler her zaman Cihazda bulunsa bile daha yavaştır. Sanırım bir yerlerde bunun son zamanlarda değiştiğini veya gelecek nesil ile değişmesi gerektiğini okudum, ama emin değilim.

Öyle görünüyor ki, GPU bu durumlarda yerel olarak çift hassasiyeti işleyemiyor, bu da neden GLDouble yerine GLFloat'ın kullanıldığını açıklıyor.

(Dediğim gibi, sadece hatırlayabildiğim kadarıyla, bir CPU'da float vs double ararken buna rastladım.)


7
GPU'lar, FPU'lardan tamamen farklı hayvanlardır. Diğerlerinin de belirttiği gibi, FPU'nun yerel formatı 80 bit çift hassasiyetlidir. Ve bu uzun zamandır. Ancak GPU'lar bu alana tek bir hassasiyetle yaklaşır. Oluyor iyi bilinen onların DP FP (çift hassasiyetli kayar nokta) performans SP FP performansının yarısı genellikle tam olduğunu. Görünüşe göre genellikle SP kayan nokta birimlerine sahipler ve çift hassasiyeti karşılamak için birimi yeniden kullanmak zorunda kalıyorlar. Bire kıyasla tam olarak iki döngü verir. Bu büyük bir performans farkı , onunla karşılaştığımda beni şaşırttı.
Csaba Toth

1
Bazı bilimsel hesaplamalar DP FP gerektirir ve önde gelen GPU üreticileri bunun etrafındaki performans cezasının reklamını yapmadı. Şimdi onlar (AMD, nVidia) DP'ye karşı SP konusunda bir şekilde gelişme gösteriyor gibi görünüyor. Intel Xeon Phi'nin birçok çekirdeği Pentium'un FPU'larını içeriyor ve Intel'in bunun çift ​​kesinlik yeteneklerini vurguladığına dikkat edin . GPGPU canavarlarıyla gerçekten rekabet edebilecekleri yer burasıdır.
Csaba Toth

13

Bu bağlıdır 32-bit veya 64 bit sistemde. 64-bit'e derlerseniz, double daha hızlı olacaktır. 64 bit (makine ve işletim sistemi) üzerinde 32 bit olarak derlendiğinde, yaklaşık% 30 daha hızlı kayar:

    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
Bu% 30'unun kullandığınız fazladan yayınlardan kaynaklanabileceğini düşündünüz mü?
Rasmus Damgaard Nielsen

@RasmusDamgaardNielsen MathDouble ile çalıştığı için yayınlar sorunun bir parçası . Ama gönderimi yanlış okudunuz: Testlerim performansımın daha iyi olduğunu gösterdi.
Bitterblue

3
Yukarıda yayınlanan sonuçlar sahtedir. Testlerim, Yayın modunda .NET 4.0 kullanan eski bir 32-bit makinede floatve doubleperformansın neredeyse aynı olduğunu gösteriyor. Her bir denemenin ardışık olarak zincirlenmiş değişkenler üzerinde çarpma, bölme ve toplama işlemlerinin uygulandığı birçok bağımsız denemenin ortalaması alındığında% 0,3'ten daha az fark (derleyici optimizasyonlarının araya girmesini önlemek için). Birlikte testlerin ikinci seti denedik Math.Sin()ve Math.Sqrt()hem de aynı sonuçlar aldık.
Özel Sos

12

Bununla birlikte, kayan noktaların tercih edildiği bazı durumlar da vardır - örneğin OpenGL kodlamasında, çoğu GPU'da GLDouble'dan daha verimli olduğu için GLFloat veri türünü (genellikle doğrudan 16 bit kayan nokta ile eşlenir) kullanmak çok daha yaygındır.


3
Belki daha yüksek veri çıkışı nedeniyle? Bir sayı matrisiniz varsa (z-arabelleği vb.), Veri boyutu daha önemli hale gelir ve kayan nokta ile çift arasındaki dönüşümlerden kaçınmak işlemeyi hızlandırır. Tahminimce.
Lucero

2
Kuşkusuz verim. Ayrıca özel bağlam göz önüne alındığında, kayan noktalara göre çiftler kullanılarak elde edilecek görünür bir şey yoktur, bu yüzden neden belleği boşa harcayın - özellikle GPU'larda CPU'lardan daha kısa arzda olduğu için
Cruachan

1
Verimlilik ve ayrıca SP FP'nin (tek duyarlıklı kayan nokta) DP FP'den (çift duyarlıklı) GPU dahili FPU'larının yerel formatıdır. @ Mene'nin cevabına yaptığım yorumu görün. GPU'lar ve CPU FPU'lar çok farklı hayvanlar, CPU'nun FPU'su DP FP'yi düşünüyor.
Csaba Toth

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.