Bu tür bir soru yinelenmektedir ve "MATLAB yüksek düzeyde optimize edilmiş kütüphaneler kullanır" veya "MATLAB, MKL'yi bir kez Yığın Taşması için kullanır.
Tarih:
Matris çarpımı (Matris-vektör, vektör-vektör çarpımı ve birçok matris ayrışması ile birlikte) doğrusal cebirdeki en önemli problemlerdir. Mühendisler bu sorunları bilgisayarlardan beri ilk günlerden beri çözüyorlar.
Tarih konusunda uzman değilim, ama görünüşe göre herkes FORTRAN versiyonunu basit döngülerle yeniden yazdı. Daha sonra bazı doğrusallaştırma, çözülmesi için en doğrusal cebir problemlerinin ihtiyaç duyduğu "çekirdeklerin" (temel rutinler) tanımlanmasıyla ortaya çıktı. Bu temel işlemler daha sonra aşağıdaki temel spesifikasyonda standardize edildi: Temel Lineer Cebir Alt Programları (BLAS). Mühendisler daha sonra kodlarında bu standart, iyi test edilmiş BLAS rutinlerini çağırarak işlerini daha kolay hale getirdiler.
BLAS:
BLAS seviye 1'den (skaler-vektör ve vektör-vektör operasyonlarını tanımlayan ilk versiyon) seviye 2'ye (vektör-matris operasyonları) seviye 3'e (matris-matris operasyonları) dönüştü ve gittikçe daha fazla "çekirdek" sağladı. ve temel lineer cebir işlemlerinden daha fazlası. Orijinal FORTRAN 77 uygulamaları Netlib'in web sitesinde hala mevcuttur .
Daha iyi performansa doğru:
Böylece yıllar boyunca (özellikle BLAS seviye 1 ve seviye 2 sürümleri arasında: 80'lerin başı), donanım vektör işlemlerinin ve önbellek hiyerarşilerinin ortaya çıkmasıyla değişti. Bu gelişmeler BLAS altyordamlarının performansını önemli ölçüde artırmayı mümkün kıldı. Farklı satıcılar daha sonra daha verimli olan BLAS rutinlerini uygulamaya koydu.
Tüm tarihi uygulamaları bilmiyorum (o zamanlar doğmadım veya bir çocuk değilim), ancak en dikkate değer olanlardan ikisi 2000'lerin başında çıktı: Intel MKL ve GotoBLAS. Matlab'ınız çok iyi, optimize edilmiş bir BLAS olan ve gördüğünüz harika performansı açıklayan Intel MKL'yi kullanıyor.
Matris çarpımı ile ilgili teknik detaylar:
Öyleyse Matlab (MKL) neden bu kadar hızlı dgemm
(çift duyarlıklı genel matris-matris çarpımı)? Basit bir ifadeyle: çünkü vektörleştirmeyi ve verilerin iyi önbelleğe alınmasını kullanır. Daha karmaşık terimlerle: Jonathan Moore tarafından sağlanan makaleye bakın .
Temel olarak, sağladığınız C ++ kodunda çarpma işlemini gerçekleştirdiğinizde, hiç önbellek dostu olmazsınız. Dizileri sıralamak için bir dizi işaretçi oluşturduğunuzdan şüphelendiğimden, "matice2" nin k-sütununa iç döngünüzdeki erişiminiz matice2[m][k]
çok yavaştır. Gerçekten, eriştiğinizde matice2[0][k]
, matrisinizin 0 dizisinin k-th öğesini almanız gerekir. Sonra bir sonraki yinelemede, matice2[1][k]
başka bir dizinin (dizi 1) k-th öğesi olan erişmeniz gerekir . Sonra bir sonraki yinelemede başka bir diziye erişirsiniz, vb ... Tüm matris matice2
en yüksek önbelleklere sığmadığından (8*1024*1024
bayt büyüktür), program istenen öğeyi ana bellekten almalı ve çok fazla kaybetmelidir. zaman.
Matrisin yerini değiştirdiyseniz, erişimler bitişik bellek adreslerinde olur, kodunuz çok daha hızlı çalışır çünkü artık derleyici önbellekteki tüm satırları aynı anda yükleyebilir. Bu değiştirilmiş sürümü deneyin:
timer.start();
float temp = 0;
//transpose matice2
for (int p = 0; p < rozmer; p++)
{
for (int q = 0; q < rozmer; q++)
{
tempmat[p][q] = matice2[q][p];
}
}
for(int j = 0; j < rozmer; j++)
{
for (int k = 0; k < rozmer; k++)
{
temp = 0;
for (int m = 0; m < rozmer; m++)
{
temp = temp + matice1[j][m] * tempmat[k][m];
}
matice3[j][k] = temp;
}
}
timer.stop();
Böylece, önbellek konumunun kodunuzun performansını nasıl önemli ölçüde artırdığını görebilirsiniz. Şimdi gerçekdgemm
uygulamalar bunu çok geniş bir seviyeye kadar kullanıyor: TLB'nin büyüklüğüne göre tanımlanmış matris blokları üzerinde çarpımı gerçekleştiriyorlar (Çeviri lookaside tamponu, uzun öykü kısa: etkili bir şekilde önbelleğe alınabilir), böylece işlemciye akıyorlar tam olarak işleyebileceği veri miktarı. Diğer yönü vektörleştirme, platformlar arası C ++ kodunuzdan gerçekten yapamayacağınız optimum talimat verimi için işlemcinin vektörleştirilmiş talimatlarını kullanır.
Son olarak, bunun Strassen veya Coppersmith-Winograd algoritması nedeniyle yanlış olduğunu iddia eden insanlar, yukarıda belirtilen donanım hususları nedeniyle her iki algoritma da pratikte uygulanamaz.