BLAS uygulamalarının aynı sonucu vereceği garanti ediliyor mu?


17

İki farklı BLAS uygulaması göz önüne alındığında, tam olarak aynı kayan nokta hesaplamaları yapmasını ve aynı sonuçları döndürmesini bekleyebilir miyiz? Veya örneğin skaler bir ürünü ve bir ( x 1 y 1 + x 2 y) şeklinde hesaplayabilir mi? 2 ) + ( x 3 y 3 + x 4

((x1y1+x2y2)+x3y3)+x4y4
bu yüzden muhtemelen IEEE kayan nokta aritmetiğinde farklı sonuç verir mi?
(x1y1+x2y2)+(x3y3+x4y4),

1
Bu konuda BLAS kalitesi ile ilgili bazı şikayetler var , sayfada CBLAS'ı arayın. Bu, sadece aynı sonucu vermediklerini değil, aynı zamanda hepsinin herhangi bir görev için yeterince doğru olduğunu değil ...
Szabolcs

Yanıtlar:


15

Hayır, bu garanti edilmez. Herhangi bir optimizasyon olmadan bir NETLIB BLAS kullanıyorsanız, sonuçların aynı olduğu çoğunlukla doğrudur. Ancak BLAS ve LAPACK'in herhangi bir pratik kullanımı için yüksek derecede optimize edilmiş bir paralel BLAS kullanılır. Paralelleştirme, yalnızca bir CPU'nun vektör kayıtlarında paralel olarak çalışsa bile, tek terimlerin değerlendirilme sırasının değişmesine ve toplamın sırasının da değişmesine neden olur. Şimdi sonuçların aynı olmadığı IEEE standardındaki eksik ilişkisel özellikten kaynaklanmaktadır. Yani tam olarak bahsettiğiniz şey olabilir.

NETLIB BLAS'ta skaler ürün sadece bir faktör 5 tarafından açılan bir döngü içindir:

DO I = MP1,N,5
          DTEMP = DTEMP + DX(I)*DY(I) + DX(I+1)*DY(I+1) +
     $            DX(I+2)*DY(I+2) + DX(I+3)*DY(I+3) + DX(I+4)*DY(I+4)
END DO

ve her bir çarpma anında DTEMP'ye eklenirse veya 5 bileşenin tamamı önce toplanır ve sonra DTEMP'ye eklenirse derleyiciye bağlıdır. OpenBLAS'ta mimariye bağlı olarak daha karmaşık bir çekirdek var:

 __asm__  __volatile__
    (
    "vxorpd     %%ymm4, %%ymm4, %%ymm4               \n\t"
    "vxorpd     %%ymm5, %%ymm5, %%ymm5               \n\t"
    "vxorpd     %%ymm6, %%ymm6, %%ymm6               \n\t"
    "vxorpd     %%ymm7, %%ymm7, %%ymm7               \n\t"

    ".align 16                           \n\t"
    "1:                          \n\t"
        "vmovups                  (%2,%0,8), %%ymm12         \n\t"  // 2 * x
        "vmovups                32(%2,%0,8), %%ymm13         \n\t"  // 2 * x
        "vmovups                64(%2,%0,8), %%ymm14         \n\t"  // 2 * x
        "vmovups                96(%2,%0,8), %%ymm15         \n\t"  // 2 * x

    "vmulpd      (%3,%0,8), %%ymm12, %%ymm12 \n\t"  // 2 * y
    "vmulpd    32(%3,%0,8), %%ymm13, %%ymm13 \n\t"  // 2 * y
    "vmulpd    64(%3,%0,8), %%ymm14, %%ymm14 \n\t"  // 2 * y
    "vmulpd    96(%3,%0,8), %%ymm15, %%ymm15 \n\t"  // 2 * y

    "vaddpd      %%ymm4 , %%ymm12, %%ymm4 \n\t"  // 2 * y
    "vaddpd      %%ymm5 , %%ymm13, %%ymm5 \n\t"  // 2 * y
    "vaddpd      %%ymm6 , %%ymm14, %%ymm6 \n\t"  // 2 * y
    "vaddpd      %%ymm7 , %%ymm15, %%ymm7 \n\t"  // 2 * y

    "addq       $16 , %0	  	     \n\t"
	"subq	        $16 , %1            \n\t"      
    "jnz        1b                   \n\t"
...

skaler ürünü 4 uzunluktaki küçük skaler ürünlere böler ve toplar.

ATLAS, MKL, ESSL, ... gibi diğer tipik BLAS uygulamalarını kullanarak bu sorun aynı kalır çünkü her BLAS uygulaması hızlı kod almak için farklı optimizasyonlar kullanır. Ama bildiğim kadarıyla gerçekten hatalı sonuçlara neden olmak için yapay bir örneğe ihtiyaç var.

BLAS kitaplığının aynı sonuçlar için döndürülmesi gerekiyorsa (aynı şekilde bit), aşağıdaki gibi çoğaltılabilir bir BLAS kitaplığı kullanılmalıdır:


8

Kısa Cevap

İşlemleri aynı sırayla yürütmek için iki BLAS uygulaması yazılırsa ve kütüphaneler aynı derleyici bayrakları ve aynı derleyici kullanılarak derlenmişse, size aynı sonucu verecektir. Kayan nokta aritmetiği rastgele değildir , bu nedenle iki özdeş uygulama aynı sonuçları verecektir.

Ancak, performans uğruna bu davranışı kırabilecek çeşitli şeyler var ...

Daha Uzun Cevap

IEEE ayrıca her bir işlemin nasıl davranması gerektiğine ek olarak bu işlemlerin gerçekleştirilme sırasını da belirler . Ancak, BLAS uygulamanızı "-ffast-math" gibi seçeneklerle derlerseniz, derleyici tam aritmetik olarak doğru olabilecek ancak IEEE kayan noktasında "doğru" olmayan dönüşümler gerçekleştirebilir. Kanonik örnek, işaret ettiğiniz gibi kayan nokta eklemenin ilişkilendirilemezliğidir. Daha agresif optimizasyon ayarlarında, ilişkilendirilebilirlik varsayılır ve işlemci, işlemleri yeniden sipariş ederek mümkün olduğunca paralel olarak yapar.

Diğer standart kırma davranışı, FMA (sigortalı çarpma-ekleme) talimatlarının kullanılmasıyla gelir. Bunlar matris çarpımı gibi işlemlerde belirgindir ve rutininizin verimini ikiye katlama potansiyeline sahiptir . Ancak operasyonu gerçekleştiriyorlarbir+b*cve tek bir kayan nokta yuvarlama basamağı oluşturur. Bu, IEEE standardından sapar ve bu işlemin iki yuvarlama adımı olmasını gerektirir. Bu, FMA sonucunu aslında IEEE'den daha doğru hale getirir , ancak teknik olarak standart kırma davranışıdır.


3
Msgstr "Kayan nokta aritmetiği rastgele değil" . Bunun açıkça belirtilmesi üzücü, ancak görünüşe göre çok fazla insan bunun olduğunu düşünüyor ...
boru

Öngörülemeyen ve rastgele oldukça benzer görünüyor ve bir çok intro programlama sınıfı "hiçbir zaman şamandıraları eşitlik için karşılaştırmayın" diyor ve bu da tam değerin tamsayılarla aynı şekilde güvenilemeyeceği izlenimini veriyor.
Tyler Olsen

@TylerOlsen Bu soru ile ilgili değildir ve bu yüzden bu sınıflar böyle şeyler söylemez, ancak IIRC, eşitliğe güvenilemeyen bir derleyici hata sınıfı vardı. Örneğin, belirli bir açıdan rastgele kadar iyi olan bazen başarısız if (x == 0) assert(x == 0) olabilir .
Kirill

@Kirill Üzgünüm, birçok insanın kayan noktanın nasıl çalıştığını gerçekten öğrenmediği noktasını anlatmaya çalışıyordum. Tarihsel noktaya gelince, bu biraz korkutucu, ama oyuna girmeden önce çözülmüş olmalı.
Tyler Olsen

@TylerOlsen Hata! Benim örneğim yanlış. if (x != 0) assert(x != 0)Genişletilmiş hassasiyetli aritmetik nedeniyle olmalıdır .
Kirill

4

Genel olarak, hayır. İlişkilendirmeyi bir kenara bırakmak, derleyici bayraklarının seçimi (örneğin, SIMD talimatları etkin, sigortalı çarpma eki kullanımı vb.) Veya donanımı (örneğin, genişletilmiş hassasiyet olsun) kullanılıp kullanılmadığını) farklı sonuçlar doğurabilir.

Tekrarlanabilir BLAS uygulamaları elde etmek için bazı çabalar vardır. Daha fazla bilgi için ReproBLAS ve ExBLAS'a bakınız .


1
Ayrıca Intel'in MKL BLAS'ın son sürümlerindeki Koşullu Sayısal Yeniden Üretilebilirlik (CNR) özelliğine de bakın. Bu tekrarlanabilirlik düzeyini elde etmenin tipik olarak hesaplamalarınızı yavaşlatacağını ve onları çok yavaşlatabileceğini unutmayın!
Brian Borchers
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.