BLAS nasıl bu kadar olağanüstü bir performans elde ediyor?


108

Meraktan dolayı kendi matris çarpım işlevimi BLAS uygulamasına göre karşılaştırmaya karar verdim ... Sonuçtan en az şaşıran şey diyecektim:

Özel Uygulama, 10 1000x1000 matris çarpımı denemesi:

Took: 15.76542 seconds.

BLAS Uygulaması, 10 1000x1000 matris çarpımı denemesi:

Took: 1.32432 seconds.

Bu, tek hassas kayan noktalı sayılar kullanıyor.

Uygulamam:

template<class ValT>
void mmult(const ValT* A, int ADim1, int ADim2, const ValT* B, int BDim1, int BDim2, ValT* C)
{
    if ( ADim2!=BDim1 )
        throw std::runtime_error("Error sizes off");

    memset((void*)C,0,sizeof(ValT)*ADim1*BDim2);
    int cc2,cc1,cr1;
    for ( cc2=0 ; cc2<BDim2 ; ++cc2 )
        for ( cc1=0 ; cc1<ADim2 ; ++cc1 )
            for ( cr1=0 ; cr1<ADim1 ; ++cr1 )
                C[cc2*ADim2+cr1] += A[cc1*ADim1+cr1]*B[cc2*BDim1+cc1];
}

İki sorum var:

  1. Bir matris-matris çarpımının şöyle dediği göz önüne alındığında: nxm * mxn, n * n * m çarpımları gerektirir, yani 1000 ^ 3 veya 1e9 işlemlerinin üzerindeki durumda. 2,6 Ghz işlemcimde BLAS'ın 10 * 1e9 işlemlerini 1,32 saniyede yapması nasıl mümkün olabilir? Çoklu şehirler tek bir operasyon olsa ve başka hiçbir şey yapılmasa bile, ~ 4 saniye sürecektir.
  2. Uygulamam neden bu kadar yavaş?

17
BLAS, alandaki uzmanlar tarafından bir yandan diğer yana optimize edilmiştir. Sanırım
çipinizdeki

3
Yine de 2,63E9 döngü / saniye işlemcide 1,3 saniyede 1E10 işlemlerini nasıl yaparsınız?
DeusAduro

9
Çoklu yürütme birimleri, boru hattı ve Tek Yönerge Çoklu Verileri ((SIMD), aynı işlemi aynı anda birden fazla işlenen çifti üzerinde yapmak anlamına gelir). Bazı derleyiciler SIMD birimlerini ortak yongalarda hedefleyebilir, ancak hemen hemen her zaman açık bir şekilde açmanız gerekir ve bunların nasıl çalıştığını bilmenize yardımcı olur ( en.wikipedia.org/wiki/SIMD ). Önbellek ıskalarına karşı sigortalamak neredeyse kesinlikle zor olan kısımdır.
dmckee --- eski moderatör yavru kedi

13
Varsayım yanlıştır. Bilinen daha iyi algoritmalar var, bkz. Wikipedia.
MSalters

2
@DeusAduro: Eigen ile rekabet edebilecek bir matris matris ürünü nasıl yazılır? Önbellek açısından verimli bir matris-matris ürününün nasıl uygulanacağına dair küçük bir örnek yayınladım.
Michael Lehn

Yanıtlar:


141

Robert A. van de Geijn ve Enrique S. Quintana-Ortí'nin yazdığı The Science of Programming Matrix Computations adlı harika kitap iyi bir başlangıç ​​noktasıdır . Ücretsiz bir indirme sürümü sağlarlar.

BLAS üç seviyeye ayrılmıştır:

  • Seviye 1, yalnızca vektörler üzerinde çalışan bir dizi doğrusal cebir fonksiyonunu tanımlar. Bu işlevler vektörleştirmeden yararlanır (örneğin SSE kullanımından).

  • Seviye 2 fonksiyonları matris vektör işlemleridir, örneğin bazı matris vektör çarpımı. Bu işlevler Seviye1 işlevleri açısından uygulanabilir. Bununla birlikte, paylaşılan belleğe sahip bazı çok işlemcili mimariden yararlanan özel bir uygulama sağlayabilirseniz, bu işlevlerin performansını artırabilirsiniz.

  • Seviye 3 fonksiyonları, matris-matris çarpımı gibi işlemlerdir. Yine bunları Seviye2 işlevleri açısından uygulayabilirsiniz. Ancak Seviye3 işlevleri, O (N ^ 2) verileri üzerinde O (N ^ 3) işlemleri gerçekleştirir. Dolayısıyla, platformunuzun bir önbellek hiyerarşisi varsa, önbellek için optimize edilmiş / önbellek dostu özel bir uygulama sağlarsanız performansı artırabilirsiniz . Bu kitapta güzelce anlatılıyor. Seviye3 işlevlerinin ana desteği önbellek optimizasyonundan gelir. Bu artış, paralellik ve diğer donanım optimizasyonlarından gelen ikinci artışı önemli ölçüde aşıyor.

Bu arada, yüksek performanslı BLAS uygulamalarının çoğu (veya hatta tümü) Fortran'da GERÇEKLEŞTİRİLMEMEKTEDİR. ATLAS, C'de uygulanmaktadır. GotoBLAS / OpenBLAS, C'de ve onun performans açısından kritik kısımları Assembler'da uygulanmaktadır. Sadece BLAS'ın referans uygulaması Fortran'da uygulanmaktadır. Bununla birlikte, tüm bu BLAS uygulamaları, LAPACK'e bağlanabilecek şekilde bir Fortran arayüzü sağlar (LAPACK tüm performansını BLAS'tan alır).

Optimize edilmiş derleyiciler bu bakımdan küçük bir rol oynar (ve GotoBLAS / OpenBLAS için derleyici hiç önemli değildir).

IMHO hiçbir BLAS uygulaması, Coppersmith – Winograd algoritması veya Strassen algoritması gibi algoritmaları kullanmaz. Sebebinden tam olarak emin değilim, ama bu benim tahminim:

  • Belki de bu algoritmaların önbellek için optimize edilmiş bir uygulamasını sağlamak mümkün değildir (yani kazanacağınızdan daha fazlasını kaybedersiniz)
  • Bu algoritmalar sayısal olarak kararlı değildir. BLAS, LAPACK'in hesaplamalı çekirdeği olduğundan, bu bir hayırdır.

Düzenle / Güncelle:

Bu konuyla ilgili yeni ve çığır açan kağıt, BLIS kağıtlarıdır . Son derece iyi yazılmışlar. "Yüksek Performanslı Hesaplama için Yazılım Temelleri" dersim için matris-matris ürününü kağıtlarını takip ederek uyguladım. Aslında matris-matris çarpımının birkaç çeşidini uyguladım. En basit varyantlar tamamen düz C ile yazılmıştır ve 450 satırdan az koda sahiptir. Diğer tüm varyantlar yalnızca döngüleri optimize eder

    for (l=0; l<MR*NR; ++l) {
        AB[l] = 0;
    }
    for (l=0; l<kc; ++l) {
        for (j=0; j<NR; ++j) {
            for (i=0; i<MR; ++i) {
                AB[i+j*MR] += A[i]*B[j];
            }
        }
        A += MR;
        B += NR;
    }

Matris-matris ürününün genel performansı yalnızca bu döngülere bağlıdır. Zamanın yaklaşık% 99,9'u burada geçiriliyor. Diğer varyantlarda performansı artırmak için içsel ve derleyici kodu kullandım. Öğreticinin tüm varyantların üzerinden geçtiğini burada görebilirsiniz:

ulmBLAS: GEMM üzerine Öğretici (Matrix-Matrix Product)

BLIS belgeleri ile birlikte, Intel MKL gibi kitaplıkların böyle bir performansı nasıl elde edebileceğini anlamak oldukça kolay hale geliyor. Ve neden satır veya sütun büyük depolama kullanmanız önemli değil!

Nihai kriterler burada (projemize ulmBLAS adını verdik):

UlmBLAS, BLIS, MKL, openBLAS ve Eigen için kıyaslamalar

Başka Bir Düzenleme / Güncelleme:

Ayrıca, BLAS'ın bir doğrusal denklem sistemini çözmek gibi sayısal doğrusal cebir problemlerinde nasıl kullanıldığına dair bazı eğitimler yazdım:

Yüksek Performanslı LU Ayrıştırması

(Bu LU çarpanlarına ayırma, örneğin Matlab tarafından bir doğrusal denklem sistemini çözmek için kullanılır.)

Ben zaman bulmak için umut tanımlamak ve benzeri LU çarpanlarına bir derece ölçeklenebilir paralel uygulanmasını gerçekleştirmek için nasıl göstermek için öğretici uzatmak PLAZMA .

Tamam, işte burada: Önbellek İçin Optimize Edilmiş Paralel LU Ayrıştırmasını Kodlama

Not: Ayrıca uBLAS'ın performansını iyileştirmek için bazı deneyler yaptım. UBLAS'ın performansını artırmak (evet, kelimelerle oynayın :)) aslında oldukça basit:

UBLAS üzerinde deneyler .

İşte BLAZE ile benzer bir proje :

BLAZE üzerinde deneyler .


3
"UlmBLAS, BLIS, MKL, openBLAS ve Eigen için kıyaslamalar" için yeni bağlantı: apfel.mathematik.uni-ulm.de/~lehn/ulmBLAS/#toc3
Ahmed Fasih

IBM'in ESSL'sinin Strassen algoritmasının bir varyasyonunu kullandığı ortaya çıktı - ibm.com/support/knowledgecenter/en/SSFHY8/essl_welcome.html
ben-albrecht

2
bağlantıların çoğu öldü
Aurélien Pierre

TSoPMC'nin bir PDF dosyası yazarın cs.utexas.edu/users/rvdg/tmp/TSoPMC.pdf
Alex Shpilkin

Coppersmith-Winograd algoritması kağıt üzerinde güzel bir zaman karmaşıklığına sahip olmasına rağmen, Büyük O notasyonu çok büyük bir sabiti gizler, bu nedenle sadece gülünç derecede büyük matrisler için geçerli olmaya başlar.
Nihar Karve

26

Öncelikle BLAS, yaklaşık 50 işlevden oluşan bir arayüzdür. Arayüzün birçok rakip uygulaması vardır.

İlk olarak, büyük ölçüde ilgisiz olan şeylerden bahsedeceğim:

  • Fortran vs C, fark etmez
  • Strassen gibi gelişmiş matris algoritmaları, uygulamalar pratikte yardımcı olmadıkları için bunları kullanmazlar.

Çoğu uygulama, her işlemi küçük boyutlu matris veya vektör işlemlerine aşağı yukarı bariz bir şekilde böler. Örneğin, büyük bir 1000x1000 matris çarpımı, 50x50 matris çarpımı dizisine bölünebilir.

Bu sabit boyutlu küçük boyutlu işlemler (çekirdekler olarak adlandırılır), hedeflerinin çeşitli CPU özelliklerini kullanarak CPU'ya özgü derleme kodunda kodlanır:

  • SIMD tarzı talimatlar
  • Öğretim Düzeyi Paralellik
  • Önbellek farkındalığı

Dahası, bu çekirdekler, tipik harita azaltma tasarım modelinde birden çok iş parçacığı (CPU çekirdekleri) kullanılarak birbirine paralel olarak yürütülebilir.

En yaygın kullanılan açık kaynaklı BLAS uygulaması olan ATLAS'a bir göz atın. Birçok farklı rekabet çekirdeği vardır ve ATLAS kitaplığı oluşturma işlemi sırasında aralarında bir rekabet yürütür (hatta bazıları parametrelidir, böylece aynı çekirdek farklı ayarlara sahip olabilir). Farklı konfigürasyonları dener ve ardından belirli hedef sistem için en iyisini seçer.

(İpucu: Bu nedenle, ATLAS kullanıyorsanız, kitaplığı kendi makineniz için el ile oluşturup ayarlamanız ve daha sonra önceden oluşturulmuş bir tane kullanmanız daha iyidir.)


ATLAS artık en yaygın kullanılan açık kaynaklı BLAS uygulaması değildir. OpenBLAS (GotoBLAS'ın bir çatalı) ve BLIS (GotoBLAS'ın yeniden düzenlenmesi) tarafından aşıldı.
Robert van de Geijn

1
@ ulaff.net: Bu belki. Bu 6 yıl önce yazılmıştır. Bence şu anda en hızlı BLAS uygulaması (elbette Intel'de) Intel MKL, ancak açık kaynak değil.
Andrew Tomazos

14

İlk olarak, matris çarpımı için kullandığınızdan daha verimli algoritmalar var.

İkinci olarak, CPU'nuz aynı anda birden fazla talimat verebilir.

CPU'nuz döngü başına 3-4 komut yürütür ve SIMD birimleri kullanılıyorsa, her komut 4 float veya 2 double işler. (elbette bu rakam da doğru değildir, çünkü CPU tipik olarak döngü başına yalnızca bir SIMD talimatını işleyebilir)

Üçüncüsü, kodunuz optimal olmaktan uzaktır:

  • Ham işaretçiler kullanıyorsunuz, bu da derleyicinin bunların takma ad olabileceklerini varsayması gerektiği anlamına gelir. Derleyiciye takma ad vermediklerini söylemek için belirleyebileceğiniz derleyiciye özgü anahtar sözcükler veya bayraklar vardır. Alternatif olarak, sorunu çözen ham işaretçilerden başka türler kullanmalısınız.
  • Giriş matrislerinin her satırı / sütunu için saf bir geçiş yaparak önbelleği bozuyorsunuz. Bir sonraki bloğa geçmeden önce CPU önbelleğine uyan daha küçük bir matris bloğu üzerinde mümkün olduğunca fazla çalışma gerçekleştirmek için engellemeyi kullanabilirsiniz.
  • Tamamen sayısal görevler için, Fortran neredeyse rakipsizdir ve C ++ benzer bir hıza ulaşmak için çok fazla ikna etme gerektirir. Yapılabilir ve bunu gösteren birkaç kitaplık vardır (tipik olarak ifade şablonlarını kullanır), ancak bu önemsiz değildir ve sadece gerçekleşmez.

Teşekkürler, Justicle'ın önerisine göre doğru kodu kısıtla ekledim, fazla gelişme görmedim, blok fikirden hoşlandım. Merak ettiğim için, CPU'nun önbellek boyutunu bilmeden, optimum kod nasıl düzeltilebilir?
DeusAduro

2
Yapmıyorsun. En iyi kodu elde etmek için CPU'nun önbellek boyutunu bilmeniz gerekir. Elbette bunun dezavantajı, kodunuzu bir CPU ailesinde en iyi performans için etkili bir şekilde kodlamanızdır .
jalf

2
En azından buradaki iç döngü çok yönlü yükleri önler. Görünüşe göre bu zaten aktarılmakta olan bir matris için yazılmış. Bu yüzden BLAS'tan "sadece" bir kat daha yavaş! Ama evet, önbellek engellemenin olmaması nedeniyle hala zorlayıcı. Fortran'ın çok yardımcı olacağından emin misin? Bence burada tek elde edeceğiniz restrict, C / C ++ 'dan farklı olarak (takma ad yok) varsayılan değerdir. (Ve ne yazık ki ISO C ++ bir restrictanahtar kelimeye sahip değil , bu yüzden __restrict__onu bir uzantı olarak sağlayan derleyicilerde kullanmanız gerekir).
Peter Cordes

11

BLAS uygulaması hakkında özel olarak bilmiyorum ama Matris Çarpması için O (n3) karmaşıklığından daha iyi olan daha verimli algoritmalar var. İyi bilinen bir Strassen Algoritmasıdır


8
Strassen Algoritması sayısal olarak iki nedenle kullanılmaz: 1) Kararlı değildir. 2) Bazı hesaplamaları kaydedersiniz, ancak bu, önbellek hiyerarşilerinden yararlanabileceğiniz fiyatla birlikte gelir. Pratikte performansınızı bile kaybedersiniz.
Michael Lehn

4
Sıkıca BLAS kütüphane kaynak kodu üzerine inşa edilen Strassen Algoritmasının pratik uygulaması için, 1000x1000 problem boyutu için bile BLAS'tan daha yüksek performans sağlayan SC16'da " Strassen Algorithm Reloaded " adlı yeni bir yayın var .
Jianyu Huang

4

İkinci sorunun argümanlarının çoğu - montajcı, bloklara bölme vb. (Ama N ^ 3 algoritmalarından daha az olmamakla birlikte, gerçekten fazla gelişmiştir) - bir rol oynar. Ancak algoritmanızın düşük hızına esasen matris boyutu ve iç içe geçmiş üç döngünün talihsiz düzenlemesi neden olur. Matrisleriniz o kadar büyük ki önbelleğe aynı anda sığmıyorlar. Döngüleri, önbellekteki bir satırda olabildiğince çok yapılacak şekilde yeniden düzenleyebilirsiniz, bu şekilde önbellek yenilemelerini önemli ölçüde azaltır (BTW'nin küçük bloklara bölünmesi analog bir etkiye sahiptir, en iyisi bloklar üzerindeki döngüler benzer şekilde düzenlenirse). Kare matrisler için bir model uygulaması aşağıdadır. Bilgisayarımda zaman tüketimi, standart uygulamaya göre (sizinki gibi) yaklaşık 1: 10'du. Başka bir deyişle: "satır boyunca bir matris çarpımı programlamayın"

    void vector(int m, double ** a, double ** b, double ** c) {
      int i, j, k;
      for (i=0; i<m; i++) {
        double * ci = c[i];
        for (k=0; k<m; k++) ci[k] = 0.;
        for (j=0; j<m; j++) {
          double aij = a[i][j];
          double * bj = b[j];
          for (k=0; k<m; k++)  ci[k] += aij*bj[k];
        }
      }
    }

Bir not daha: Bu uygulama, bilgisayarımda hepsini BLAS rutini cblas_dgemm ile değiştirmekten daha iyidir (bilgisayarınızda deneyin!). Ancak çok daha hızlı (1: 4) doğrudan Fortran kütüphanesinin dgemm_'sini çağırıyor. Bence bu rutin aslında Fortran değil, assembler kodu (kütüphanede ne olduğunu bilmiyorum, kaynaklarım yok). Benim için tamamen belirsiz olan cblas_dgemm'in neden o kadar hızlı olmadığı, çünkü bildiğim kadarıyla sadece dgemm_ için bir paketleyicidir.


3

Bu gerçekçi bir hızlanma. SIMD assembler ile C ++ kodu üzerinden neler yapılabileceğine dair bir örnek için, bazı örnek iPhone matris fonksiyonlarına bakın - bunlar C versiyonundan 8 kat daha hızlıydı ve hatta "optimize edilmiş" montaj bile değil - henüz boru hattı yok ve orada gereksiz yığın işlemidir.

Ayrıca kodunuz " kısıtlanmış doğru " değildir - derleyici C'yi değiştirdiğinde A ve B'yi değiştirmediğini nasıl anlar?


Elbette işlevi mmult (A ..., A ..., A) gibi çağırdıysanız; kesinlikle beklenen sonucu alamazsın. Yine, BLAS'ı yenmeye / yeniden uygulamaya çalışmadığım halde, gerçekten ne kadar hızlı olduğunu görmeme rağmen, hata kontrolü akılda değildi, sadece temel işlevler.
DeusAduro

3
Üzgünüm, açık olmak gerekirse, şunu söylüyorum, işaretçilerinize "kısıtlama" koyarsanız, çok daha hızlı kod alırsınız. Bunun nedeni, C'yi her değiştirdiğinizde, derleyicinin A ve B'yi yeniden yüklemesine gerek kalmaması - iç döngüyü önemli ölçüde hızlandırmasıdır. Bana inanmıyorsanız, demontajı kontrol edin.
Justicle

@DeusAduro: Bu hata kontrolü değildir - derleyicinin iç döngüdeki B [] dizisine erişimleri optimize edememesi olasıdır çünkü A ve C işaretçilerinin hiçbir zaman B'yi diğer adıyla değiştirmediğini anlayamayabilir. dizi. Örtüşme olsaydı, iç döngü yürütülürken B dizisindeki değerin değişmesi mümkün olurdu. B [] değerine erişimi iç döngüden çıkarmak ve yerel bir değişkene koymak, derleyicinin B [] 'ye sürekli erişimden kaçınmasını sağlayabilir.
Michael Burr

1
Hmmm, bu yüzden ilk olarak VS 2008'de '__restrict' anahtar kelimesini kullanmayı denedim, A, B ve C'ye uygulandı. Bu sonuçta hiçbir değişiklik göstermedi. Ancak erişimi B'ye, en içteki döngüden dışarıdaki döngüye taşımak, zamanı ~% 10 iyileştirdi.
DeusAduro

1
Maalesef VC hakkında emin değilim, ancak GCC ile etkinleştirmeniz gerekiyor -fstrict-aliasing. Burada "kısıtlama" nın daha iyi bir açıklaması var: cellperformance.beyond3d.com/articles/2006/05/…
Justicle

2

MM çarpımındaki orijinal kodla ilgili olarak, çoğu işlem için bellek referansı, kötü performansın ana nedenidir. Bellek, önbellekten 100-1000 kat daha yavaş çalışıyor.

Hızın çoğu, MM çarpımında bu üçlü döngü işlevi için döngü optimizasyon tekniklerinin kullanılmasından gelir. İki ana döngü optimizasyon tekniği kullanılır; açma ve engelleme. Açma ile ilgili olarak, en dıştaki iki döngüyü açar ve önbellekte verilerin yeniden kullanılması için engelleriz. Dış döngü açma, tüm işlem boyunca farklı zamanlarda aynı verilere yönelik bellek referanslarının sayısını azaltarak veri erişimini geçici olarak optimize etmeye yardımcı olur. Döngü dizininin belirli bir sayıda engellenmesi, verilerin önbellekte tutulmasına yardımcı olur. L2 önbelleği veya L3 önbelleği için optimize etmeyi seçebilirsiniz.

https://en.wikipedia.org/wiki/Loop_nest_optimization


-24

Bir çok sebepten ötürü.

Birincisi, Fortran derleyicileri oldukça optimize edilmiştir ve dil onların böyle olmalarına izin verir. C ve C ++ dizi yönetimi açısından çok gevşektir (örneğin, aynı bellek alanına atıfta bulunan işaretçilerin durumu). Bu, derleyicinin önceden ne yapacağını bilemeyeceği ve genel kod oluşturmaya zorlandığı anlamına gelir. Fortran'da vakalarınız daha akıcı hale getirilir ve derleyici, ne olacağı konusunda daha iyi kontrole sahiptir, bu da daha fazla optimizasyon yapmasına izin verir (örneğin, kayıtlar kullanarak).

Başka bir şey de Fortran'ın malzemeleri sütun şeklinde depolaması, C'nin ise verileri satır bazında saklaması. Kodunuzu kontrol etmedim, ancak ürünü nasıl çalıştırdığınız konusunda dikkatli olun. C'de satır bazında taramanız gerekir: bu şekilde dizinizi bitişik bellek boyunca tararsınız, önbellek eksikliklerini azaltırsınız. Önbellek kaçırma, verimsizliğin ilk kaynağıdır.

Üçüncüsü, kullandığınız blas uygulamasına bağlıdır. Bazı uygulamalar assembler'da yazılabilir ve kullandığınız belirli işlemci için optimize edilebilir. Netlib versiyonu fortran 77'de yazılmıştır.

Ayrıca, çoğu tekrarlanan ve gereksiz olan birçok işlem yapıyorsunuz. İndeksi elde etmek için tüm bu çarpımlar performans için zararlıdır. BLAS'ta bunun nasıl yapıldığını gerçekten bilmiyorum, ancak pahalı işlemleri önlemek için birçok numara var.

Örneğin, kodunuzu bu şekilde yeniden çalışabilirsiniz

template<class ValT>
void mmult(const ValT* A, int ADim1, int ADim2, const ValT* B, int BDim1, int BDim2, ValT* C)
{
if ( ADim2!=BDim1 ) throw std::runtime_error("Error sizes off");

memset((void*)C,0,sizeof(ValT)*ADim1*BDim2);
int cc2,cc1,cr1, a1,a2,a3;
for ( cc2=0 ; cc2<BDim2 ; ++cc2 ) {
    a1 = cc2*ADim2;
    a3 = cc2*BDim1
    for ( cc1=0 ; cc1<ADim2 ; ++cc1 ) {
          a2=cc1*ADim1;
          ValT b = B[a3+cc1];
          for ( cr1=0 ; cr1<ADim1 ; ++cr1 ) {
                    C[a1+cr1] += A[a2+cr1]*b;
           }
     }
  }
} 

Deneyin, eminim bir şeyler kurtaracaksınız.

1 numaralı sorunuzun nedeni, önemsiz bir algoritma kullanıyorsanız, matris çarpımının O (n ^ 3) olarak ölçeklenmesidir. Çok daha iyi ölçeklenen algoritmalar var .


36
Bu cevap tamamen yanlış üzgünüm. BLAS uygulamaları fortran'da yazılmaz. Performans açısından kritik kod, montajda yazılır ve bugünlerde en yaygın olanlar bunun üzerinde C ile yazılır. Ayrıca BLAS, arayüzün bir parçası olarak satır / sütun sırasını belirtir ve uygulamalar herhangi bir kombinasyonu işleyebilir.
Andrew Tomazos

10
Evet, bu cevap olduğunu tamamen yanlış. Maalesef genel anlamsızlıkla dolu, örneğin, BLAS'ın Fortran yüzünden daha hızlı olduğu iddiası. 20 (!) Olumlu puan almak kötü bir şeydir. Şimdi bu mantıksızlık Stackoverflow'un popülaritesi nedeniyle daha da yayılıyor!
Michael Lehn

12
Optimize edilmemiş referans uygulamasını üretim uygulamalarıyla karıştırdığınızı düşünüyorum. Referans uygulama sadece kütüphanenin arayüzünü ve davranışını belirtmek içindir ve tarihsel nedenlerle Fortran'da yazılmıştır. Üretim kullanımı için değildir. Üretimde insanlar, referans uygulama ile aynı davranışı sergileyen optimize edilmiş uygulamaları kullanır. ATLAS'ın (Octave - Linux "MATLAB" ı destekleyen) iç kısımlarını inceledim ve ilk elden C / ASM ile yazıldığını doğrulayabilirim. Ticari uygulamalar da neredeyse kesin.
Andrew Tomazos

5
@KyleKanos: Evet, işte ATLAS'ın kaynağı: sourceforge.net/projects/math-atlas/files/Stable/3.10.1 Bildiğim kadarıyla en yaygın kullanılan açık kaynak taşınabilir BLAS uygulaması. C / ASM ile yazılmıştır. Intel gibi yüksek performanslı CPU üreticileri de özellikle çipleri için optimize edilmiş BLAS uygulamaları sağlar. Intel kitaplığının alt düzey bölümlerinin (duuh) x86 derlemesinde yazıldığını garanti ediyorum ve orta düzey bölümlerin C veya C ++ ile yazılacağından eminim.
Andrew Tomazos

9
@KyleKanos: Kafan karıştı. Netlib BLAS, referans uygulamasıdır. Referans uygulama, optimize edilmiş uygulamalardan çok daha yavaştır ( performans karşılaştırmasına bakın ). Birisi bir kümede netlib BLAS kullandığını söylediğinde, bu aslında netlib referans uygulamasını kullandıkları anlamına gelmez. Bu çok aptalca olurdu. Bu sadece netlib blas ile aynı arayüze sahip bir lib kullandıkları anlamına gelir.
Andrew Tomazos
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.