Titik awal yang baik adalah buku hebat The Science of Programming Matrix Computations oleh Robert A. van de Geijn dan Enrique S. Quintana-Ortí. Mereka menyediakan versi unduhan gratis.
BLAS dibagi menjadi tiga tingkatan:
Level 1 mendefinisikan sekumpulan fungsi aljabar linier yang beroperasi hanya pada vektor. Fungsi-fungsi ini mendapatkan keuntungan dari vektorisasi (misalnya dari penggunaan SSE).
Fungsi level 2 adalah operasi matriks-vektor, misalnya beberapa hasil kali matriks-vektor. Fungsi-fungsi ini dapat diimplementasikan dalam kaitannya dengan fungsi Level1. Namun, Anda dapat meningkatkan kinerja fungsi ini jika Anda dapat menyediakan implementasi khusus yang menggunakan beberapa arsitektur multiprosesor dengan memori bersama.
Fungsi level 3 adalah operasi seperti hasil kali matriks-matriks. Sekali lagi Anda bisa mengimplementasikannya dalam kaitannya dengan fungsi Level2. Tetapi fungsi Level3 melakukan operasi O (N ^ 3) pada data O (N ^ 2). Jadi, jika platform Anda memiliki hierarki cache, Anda dapat meningkatkan kinerja jika Anda menyediakan implementasi khusus yang dioptimalkan untuk cache / ramah cache . Ini dijelaskan dengan baik di buku. Peningkatan utama fungsi Level3 berasal dari pengoptimalan cache. Peningkatan ini secara signifikan melebihi dorongan kedua dari paralelisme dan pengoptimalan perangkat keras lainnya.
Ngomong-ngomong, sebagian besar (atau bahkan semua) implementasi BLAS berkinerja tinggi TIDAK diterapkan di Fortran. ATLAS diimplementasikan di C. GotoBLAS / OpenBLAS diimplementasikan di C dan kinerja bagian penting di Assembler. Hanya implementasi referensi BLAS yang dilaksanakan di Fortran. Namun, semua implementasi BLAS ini menyediakan antarmuka Fortran sehingga dapat ditautkan ke LAPACK (LAPACK mendapatkan semua kinerjanya dari BLAS).
Kompiler yang dioptimalkan memainkan peran kecil dalam hal ini (dan untuk GotoBLAS / OpenBLAS, kompiler tidak menjadi masalah sama sekali).
Implementasi IMHO no BLAS menggunakan algoritma seperti algoritma Coppersmith – Winograd atau algoritma Strassen. Saya tidak begitu yakin tentang alasannya, tapi ini tebakan saya:
- Mungkin tidak mungkin untuk menyediakan implementasi cache yang dioptimalkan dari algoritma ini (yaitu Anda akan kehilangan lebih banyak daripada Anda akan menang)
- Algoritme ini secara numerik tidak stabil. Karena BLAS adalah kernel komputasi LAPACK, ini tidak boleh dilakukan.
Edit / Perbarui:
Makalah baru dan terobosan untuk topik ini adalah makalah BLIS . Mereka ditulis dengan sangat baik. Untuk kuliah saya "Dasar-dasar Perangkat Lunak untuk Komputasi Kinerja Tinggi", saya mengimplementasikan produk matriks-matriks setelah makalah mereka. Sebenarnya saya menerapkan beberapa varian dari produk matriks-matriks. Varian paling sederhana seluruhnya ditulis dalam C biasa dan memiliki kurang dari 450 baris kode. Semua varian lainnya hanya mengoptimalkan loop
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;
}
Performa keseluruhan dari produk matriks-matriks hanya bergantung pada loop ini. Sekitar 99,9% waktu dihabiskan di sini. Dalam varian lain saya menggunakan kode intrinsik dan assembler untuk meningkatkan kinerja. Anda dapat melihat tutorial melalui semua varian di sini:
ulmBLAS: Tutorial tentang GEMM (Matrix-Matrix Product)
Bersama dengan makalah BLIS, menjadi cukup mudah untuk memahami bagaimana perpustakaan seperti Intel MKL dapat memperoleh kinerja seperti itu. Dan mengapa tidak masalah apakah Anda menggunakan penyimpanan utama baris atau kolom!
Tolok ukur terakhir ada di sini (kami menyebut proyek kami ulmBLAS):
Tolok ukur untuk ulmBLAS, BLIS, MKL, openBLAS dan Eigen
Edit / Pembaruan Lain:
Saya juga menulis beberapa tutorial tentang bagaimana BLAS digunakan untuk masalah aljabar linier numerik seperti memecahkan sistem persamaan linier:
Faktorisasi LU Kinerja Tinggi
(Faktorisasi LU ini misalnya digunakan oleh Matlab untuk menyelesaikan sistem persamaan linier.)
Saya berharap dapat menemukan waktu untuk memperpanjang tutorial untuk menjelaskan dan mendemonstrasikan bagaimana mewujudkan implementasi paralel yang sangat skalabel dari faktorisasi LU seperti di PLASMA .
Oke, ini dia: Coding a Cache Optimized Parallel LU Factorization
PS: Saya juga melakukan beberapa percobaan untuk meningkatkan kinerja uBLAS. Sebenarnya cukup mudah untuk meningkatkan (ya, mainkan kata-kata :)) kinerja uBLAS:
Eksperimen di uBLAS .
Berikut proyek serupa dengan BLAZE :
Eksperimen di BLAZE .