Kinerja perpustakaan matematika matriks Java? [Tutup]


151

Kami menghitung sesuatu yang runtime terikat oleh operasi matriks. (Beberapa detail di bawah ini jika tertarik.) Pengalaman ini mendorong pertanyaan berikut:

Apakah orang-orang memiliki pengalaman dengan kinerja perpustakaan Java untuk matematika matriks (misalnya, gandakan, terbalik, dll.)? Sebagai contoh:

Saya mencari dan tidak menemukan apa pun.


Detail perbandingan kecepatan kami:

Kami menggunakan Intel FORTRAN (ifort (IFORT) 10.1 20070913). Kami telah mengimplementasikannya kembali di Java (1.6) menggunakan Apache commons math 1.2 matrix ops, dan setuju untuk semua digit akurasinya. (Kami memiliki alasan untuk menginginkannya di Jawa.) (Java dobel, Fortran real * 8). Fortran: 6 menit, Jawa 33 menit, mesin yang sama. profil jvisualm menunjukkan banyak waktu yang dihabiskan di RealMatrixImpl. {getEntry, isValidCoordinate} (yang tampaknya hilang di Apache commons math 2.0 yang belum dirilis, tetapi 2.0 tidak lebih cepat). Fortran menggunakan rutinitas Atlas BLAS (dpotrf, dll.).

Jelas ini bisa tergantung pada kode kami di setiap bahasa, tetapi kami percaya sebagian besar waktu dalam operasi matriks yang setara.

Dalam beberapa perhitungan lain yang tidak melibatkan perpustakaan, Java belum jauh lebih lambat, dan kadang-kadang jauh lebih cepat.


Ops matriks rumit matematika setidaknya O (n ^ 3) ... buruk datang ke buruk, saya kira Anda bisa waktu dan tes ...
Calyth

2
Mengapa Anda membutuhkan invers? Untuk hampir semua aplikasi, Anda tidak perlu invers yang sebenarnya. Menghitung kebalikannya adalah ide yang buruk karena masalah stabilitas.
Ying Xiao

1
@Calyth: Ya, kita bisa mengatur waktu. Saya bertanya-tanya apakah yang lain sudah memilikinya. @Ying Xiao: Ya, invers harus dihindari. Namun, perhitungan ini tampaknya paling mudah menggunakannya. Lihat en.wikipedia.org/wiki/… .
dfrankow

2
@ Calyth Itu salah, ada metode yang lebih efisien daripada O (n ^ 3) menggunakan pendekatan divide and conquer.
starblue

1
Kinerja asli tercepat dari JCublas. Jika Anda membutuhkan aljabar linear cepat, Anda memerlukan GPU. JOCL dengan clMath mungkin juga berfungsi dan portabel untuk CPU (dan bahkan multi-platform tanpa kompilasi ulang), tapi saya belum mengujinya.
Aleksandr Dubinsky

Jawaban:


98

Hanya untuk menambahkan 2 sen saya. Saya telah membandingkan beberapa perpustakaan ini. Saya mencoba untuk mengalikan matriks 3000 dengan 3000 matriks ganda dengan dirinya sendiri. Hasilnya adalah sebagai berikut.

Menggunakan multithreaded ATLAS dengan C / C ++, Octave, Python dan R, waktu yang dibutuhkan sekitar 4 detik.

Menggunakan Jama dengan Java, waktu yang dibutuhkan adalah 50 detik.

Menggunakan Colt dan Parallel Colt dengan Java, waktu yang dibutuhkan adalah 150 detik!

Menggunakan JBLAS dengan Java, waktu yang dibutuhkan kembali sekitar 4 detik karena JBLAS menggunakan ATLAS multithreaded.

Jadi bagi saya sudah jelas bahwa perpustakaan Java tidak berkinerja terlalu baik. Namun jika seseorang harus kode di Jawa, maka opsi terbaik adalah JBLAS. Jama, Colt, dan Paralel Colt tidak cepat.


3
Saya kira Anda menggunakan mesin multicore, jadi hasil ini sangat dipengaruhi oleh apakah perpustakaan menggunakan multicore atau tidak? Untuk beberapa tujuan, misalnya ketika seseorang memparalelkan menggunakan mpi atau hadoop dll, waktu yang penting sebenarnya adalah waktu singlecore , karena implementasi mpi / hadoop menangani hal-hal yang paralel. (Setidaknya, bagi saya jblas sekitar 2,5 lebih cepat dari jama, tidak 10 kali lebih cepat dari jama seperti yang Anda dapatkan.)
Hugh Perkins

17
Saya baru saja merilis v1.0 dari netlib-java ... kinerjanya setara (dan kadang-kadang melampaui) kode Fortran, dan dapat menggunakan mesin yang dioptimalkan asli tanpa perubahan pada kode pengguna. Silakan pertimbangkan ini ketika mencari perpustakaan aljabar linier tingkat rendah. Saya juga memelihara MTJ , yang memanfaatkan netlib-java. Di Scala, gunakan Breeze (juga diberdayakan oleh netlib-java)
fommil

4
Menggunakan ND4j dan java - laptop saya yang relatif lama menyelesaikan perkalian yang disarankan dalam 219 milis. Sementara python + numpy menyelesaikannya dalam 349 milis
bennyl

2
Dan untuk menambahkan komentar terakhir saya tentang menggunakan nd4j, saya menggunakan platform-asli sebagai backend-nya, jika saya menggunakan platform-cuda, dibutuhkan sekitar 1 milidetik
bennyl

Apakah Anda menerbitkan kode untuk tolok ukur di suatu tempat?
bruziuz

108

Saya penulis Java Matrix Benchmark ( JMatBench ) dan saya akan memberikan pemikiran saya pada diskusi ini.

Ada perbedaan yang signifikan antara perpustakaan Java dan sementara tidak ada pemenang yang jelas di seluruh jajaran operasi, ada beberapa pemimpin yang jelas seperti yang dapat dilihat dalam hasil kinerja terbaru (Oktober 2013).

Jika Anda bekerja dengan matriks "besar" dan dapat menggunakan pustaka asli, maka pemenang yang jelas (sekitar 3,5x lebih cepat) adalah MTJ dengan sistem yang dioptimalkan netlib . Jika Anda membutuhkan solusi Java murni maka MTJ , OjAlgo , EJML dan Parallel Colt adalah pilihan yang baik. Untuk matriks kecil, EJML adalah pemenang yang jelas.

Perpustakaan yang tidak saya sebutkan menunjukkan masalah kinerja yang signifikan atau tidak memiliki fitur utama.


6
Hanya berpikir saya akan menyebutkan bahwa tolok ukur Anda sangat berguna! Terima kasih telah meluangkan waktu Anda ke dalamnya.
hohonuuli

1
JBLAS tampaknya mendukung SVD pada Sep '13: mikiobraun.github.io/jblas/javadoc/org/jblas/…
Leopd

kerja bagus, terima kasih banyak.
webpat

Apakah ada daftar perpustakaan yang Anda evaluasi tetapi tidak mempublikasikan hasilnya, dan alasannya?
Kevin Krumwiede

1
MTJ tampaknya ditinggalkan: repositori diarsipkan dan komit terakhir pada 2016.
Danila Piatov

51

Saya penulis utama jblas dan ingin menunjukkan bahwa saya telah merilis Versi 1.0 pada akhir Desember 2009. Saya bekerja banyak pada kemasannya, artinya sekarang Anda dapat mengunduh "toples lemak" dengan perpustakaan ATLAS dan JNI untuk Windows, Linux, Mac OS X, 32 dan 64 bit (kecuali untuk Windows). Dengan cara ini Anda akan mendapatkan kinerja asli hanya dengan menambahkan file jar ke classpath Anda. Lihat di http://jblas.org !


2
terinspirasi oleh pekerjaan Anda, saya melakukan hal serupa di netlib-java ;-)
fommil

2
Haha, aku juga, untuk jeigen :-)
Hugh Perkins

JogAmp melakukan hal yang sama, lihat jogamp-fat.jar. Ide bagus :)
gouessej

8

Saya tidak bisa mengomentari perpustakaan tertentu, tetapi pada prinsipnya ada sedikit alasan untuk operasi seperti itu menjadi lebih lambat di Jawa. Hotspot umumnya melakukan hal-hal yang Anda harapkan dilakukan oleh kompiler: kompilasi operasi matematika dasar pada variabel Java ke instruksi mesin yang sesuai (menggunakan instruksi SSE, tetapi hanya satu per operasi); akses ke elemen array dikompilasi untuk menggunakan instruksi MOV "mentah" seperti yang Anda harapkan; itu membuat keputusan tentang bagaimana mengalokasikan variabel ke register ketika itu bisa; itu memesan ulang instruksi untuk memanfaatkan arsitektur prosesor ... Pengecualian yang mungkin adalah bahwa seperti yang saya sebutkan, Hotspot hanya akan melakukan satu operasi per instruksi SSE; pada prinsipnya Anda bisa memiliki perpustakaan matriks dioptimalkan fantastis yang melakukan beberapa operasi per instruksi, meskipun saya tidak Saya tidak tahu apakah, misalnya, perpustakaan FORTRAN khusus Anda melakukannya atau apakah perpustakaan semacam itu ada. Jika ya, saat ini tidak ada cara untuk Java (atau setidaknya, Hotspot) untuk bersaing dengan itu (meskipun Anda tentu saja dapat menulis perpustakaan asli Anda sendiri dengan optimisasi panggilan dari Jawa).

Jadi apa artinya semua ini? Baik:

  • pada prinsipnya, perlu mencari-cari perpustakaan yang berkinerja lebih baik, meskipun sayangnya saya tidak bisa merekomendasikannya
  • jika kinerja benar-benar penting bagi Anda, saya akan mempertimbangkan untuk hanya mengkodekan operasi matriks Anda sendiri, karena Anda kemudian dapat melakukan optimasi tertentu yang secara umum tidak dapat dilakukan oleh perpustakaan, atau bahwa perpustakaan tertentu yang Anda gunakan tidak (jika Anda memiliki mesin multiprosesor, cari tahu apakah perpustakaan sebenarnya multithreaded)

Hambatan untuk operasi matriks sering kali masalah lokalitas data yang muncul ketika Anda perlu melintasi baris demi baris dan kolom demi kolom, misalnya dalam penggandaan matriks, karena Anda harus menyimpan data dalam urutan yang mengoptimalkan satu atau yang lain. Tetapi jika Anda menulis kode secara manual, Anda kadang-kadang dapat menggabungkan operasi untuk mengoptimalkan lokalitas data (misalnya jika Anda mengalikan matriks dengan transformasinya, Anda dapat mengubah traversal kolom menjadi traversal baris jika Anda menulis fungsi khusus alih-alih menggabungkan dua fungsi perpustakaan). Seperti biasa dalam kehidupan, perpustakaan akan memberi Anda kinerja yang tidak optimal dengan imbalan pengembangan yang lebih cepat; Anda perlu memutuskan seberapa pentingkah kinerja bagi Anda.


8

Saya baru saja membandingkan Apache Commons Math dengan jlapack.

Uji: dekomposisi nilai singular dari matriks 1024x1024 acak.

Mesin: Intel (R) Core (TM) 2 Duo CPU E6750 @ 2.66GHz, linux x64

Kode oktaf: A = rand (1024); tic; [U, S, V] = svd (A); toc

hasil waktu eksekusi
-------------------------------------------------- -------
Oktaf 36,34 detik

JDK 1.7u2 64bit
    jlapack dgesvd 37.78 dtk
    apache commons math SVD 42.24 dtk


JDK 1.6u30 64bit
    jlapack dgesvd 48.68 dtk
    apache commons math SVD 50,59 dtk

Rutinitas asli
Lapack * dipanggil dari C: 37.64 dtk
Intel MKL 6.89 dtk (!)

Kesimpulan saya adalah bahwa jlapack yang dipanggil dari JDK 1.7 sangat dekat dengan kinerja biner asli dari Lapack. Saya menggunakan perpustakaan binary lapack datang dengan distro linux dan dipanggil rutin dgesvd untuk mendapatkan matriks U, S dan VT juga. Semua tes dilakukan dengan menggunakan presisi ganda pada matriks yang persis sama setiap proses (kecuali Oktaf).

Penafian - Saya bukan ahli aljabar linier, tidak berafiliasi dengan salah satu perpustakaan di atas dan ini bukan patokan yang ketat. Ini adalah tes 'buatan sendiri', karena saya tertarik membandingkan peningkatan kinerja JDK 1,7 menjadi 1,6 serta SVD matematika umum ke jlapack.


8

Jeigen https://github.com/hughperkins/jeigen

  • membungkus perpustakaan Eigen C ++ http://eigen.tuxfamily.org , yang merupakan salah satu perpustakaan C ++ gratis tercepat yang ada
  • sintaks yang relatif singkat, misalnya 'mmul', 'sub'
  • menangani matriks yang padat dan jarang

Tes cepat, dengan mengalikan dua matriks padat, yaitu:

impor static jeigen.MatrixUtil. *;

int K = 100;
int N = 100000;
DenseMatrix A = rand(N, K);
DenseMatrix B = rand(K, N);
Timer timer = new Timer();
DenseMatrix C = B.mmul(A);
timer.printTimeCheckMilliseconds();

Hasil:

Jama: 4090 ms
Jblas: 1594 ms
Ojalgo: 2381 ms (using two threads)
Jeigen: 2514 ms
  • Dibandingkan dengan jama, semuanya lebih cepat :-P
  • Dibandingkan dengan jblas, Jeigen tidak cukup cepat, tetapi menangani matriks yang jarang.
  • Dibandingkan dengan ojalgo, Jeigen membutuhkan jumlah waktu yang sama, tetapi hanya menggunakan satu inti, jadi Jeigen menggunakan setengah dari total cpu. Jeigen memiliki sintaks terser, yaitu 'mmul' versus 'multiplyRight'

Jeigen terlihat luar biasa! Saya baru-baru ini menerapkan Eigen di Jawa menggunakan JNI dan DLL untuk memecahkan matriks jarang yang sangat besar. Versi saya dengan DLL lebih dari 20 lebih cepat dari colt paralel untuk pengujian saya (lebih dari 8000x8000 matriks). Saya berharap saya tahu tentang Jeigen!
Z boson

6

Ada patokan berbagai paket matriks yang tersedia di java di http://code.google.com/p/java-matrix-benchmark/ untuk beberapa konfigurasi perangkat keras yang berbeda. Tapi itu bukan pengganti untuk melakukan tolok ukur Anda sendiri.

Performa akan bervariasi dengan jenis perangkat keras yang Anda miliki (CPU, core, memori, cache L1-3, kecepatan bus), ukuran matriks dan algoritma yang ingin Anda gunakan. Pustaka yang berbeda memiliki concurrency yang berbeda untuk algoritma yang berbeda, sehingga tidak ada jawaban tunggal. Anda juga mungkin menemukan bahwa overhead menerjemahkan ke formulir yang diharapkan oleh perpustakaan asli meniadakan keuntungan kinerja untuk kasus penggunaan Anda (beberapa perpustakaan java memiliki opsi yang lebih fleksibel mengenai penyimpanan matriks, yang dapat digunakan untuk optimasi kinerja lebih lanjut).

Namun secara umum, JAMA, Jampack dan COLT semakin tua, dan tidak mewakili keadaan kinerja saat ini yang tersedia di Jawa untuk aljabar linier. Lebih banyak perpustakaan modern memanfaatkan lebih banyak core dan cache cpu secara lebih efektif. JAMA adalah implementasi referensi, dan cukup banyak mengimplementasikan algoritma buku teks dengan sedikit memperhatikan kinerja. COLT dan IBM Ninja adalah perpustakaan java pertama yang menunjukkan bahwa kinerja dimungkinkan di java, bahkan jika mereka tertinggal 50% di belakang perpustakaan asli.


4

Saya penulis perpustakaan la4j (Aljabar Linier untuk Jawa) dan inilah poin saya. Saya telah bekerja di la4j selama 3 tahun (rilis terbaru adalah 0.4.0 [01 Jun 2013]) dan hanya sekarang saya dapat mulai melakukan analisis dan optimasi performace karena saya baru saja membahas fungsional minimum yang diperlukan. Jadi, la4j tidak secepat yang saya inginkan tetapi saya menghabiskan banyak waktu untuk mengubahnya.

Saya saat ini di tengah porting versi baru dari la4j ke platform JMatBench . Saya berharap versi baru akan menunjukkan kinerja yang lebih baik daripada yang sebelumnya karena ada beberapa peningkatan yang saya buat di la4j seperti format matriks internal yang jauh lebih cepat, pengakses yang tidak aman dan algoritma pemblokiran cepat untuk perkalian matriks.


1
Tidak - la4j benar - benar tidak kompetitif. Lihat code.google.com/p/java-matrix-benchmark
Christopher Manning

Itu telah banyak berubah. Saya telah merilis dua versi perpustakaan sejak jawaban Anda. Rilis saat ini adalah 0.4.0. Dan itu hanya terbang.
Vladimir Kostyukov

3

Kode Linalg yang sangat bergantung pada Pentium dan kemampuan komputasi vektor prosesor selanjutnya (dimulai dengan ekstensi MMX, seperti LAPACK dan sekarang Atlas BLAS) tidak "dioptimalkan secara fantastis", tetapi hanya standar industri. Untuk meniru kinerja itu di Jawa Anda akan memerlukan perpustakaan asli. Saya memiliki masalah kinerja yang sama seperti yang Anda gambarkan (terutama, untuk dapat menghitung dekomposisi Choleski) dan tidak menemukan apa pun yang benar-benar efisien: Jama adalah Java murni, karena seharusnya hanya template dan referensi kit untuk diikuti oleh pelaksana. .. yang tidak pernah terjadi. Anda tahu Apache math commons ... Adapun COLT, saya masih harus mengujinya tetapi tampaknya sangat bergantung pada peningkatan Ninja, yang sebagian besar dicapai dengan membangun kompiler Java ad-hoc, jadi saya ragu itu akan membantu. Pada titik itu, saya pikir kita "


Poin bagus! Proyek tahap alpha dengan pembungkus JNI untuk Atlas: jblas.org . Posting blog penulis: mikiobraun.blogspot.com/2008/10/…
dfrankow

3

Kami telah menggunakan COLT untuk beberapa perhitungan keuangan serius yang cukup besar dan sangat senang dengannya. Dalam kode kami yang sangat berprofil, kami hampir tidak pernah harus mengganti implementasi COLT dengan salah satu dari kami sendiri.

Dalam pengujian mereka sendiri (jelas tidak independen) saya pikir mereka mengklaim dalam faktor 2 dari rutin assembler dioptimalkan dengan tangan Intel. Trik untuk menggunakannya dengan baik adalah memastikan bahwa Anda memahami filosofi desain mereka, dan menghindari alokasi objek yang asing.


3

Sudahkah Anda melihat Perpustakaan Intel Math Kernel ? Ia mengklaim mengungguli ATLAS . MKL dapat digunakan di Jawa melalui pembungkus JNI.


2
Kami memilikinya. a) Lisensinya lebih ketat daripada Atlas (jadi kami tidak dapat menggunakan semua komputer kami); b) itu bukan Jawa (dan seperti yang saya katakan kita punya alasan untuk ingin berada di Jawa).
dfrankow

yaitu, ini bukan jawaban untuk pertanyaan saya tentang perpustakaan Java (tapi saya tidak punya reputasi untuk downvote).
dfrankow

@dfrankow: Saya telah memperbarui jawaban saya untuk mengatasi kekhawatiran Anda tentang penggunaannya di Jawa.
Zach Scrivena

1
+1, Jika kecepatan yang Anda cari, ini sepertinya cara untuk pergi
Gab Royer

2
Tautan terakhir rusak.
gouessej


2

Anda mungkin ingin memeriksa proyek jblas . Ini adalah perpustakaan Java yang relatif baru yang menggunakan BLAS, LAPACK dan ATLAS untuk operasi matriks berkinerja tinggi.

Pengembang telah memposting beberapa tolok ukur di mana jblas memberikan hasil yang menguntungkan terhadap MTJ dan Colt.


2

Untuk aplikasi grafis 3d, implementasi vektor lwjgl.util dilakukan di atas jblas yang disebutkan di atas dengan faktor sekitar 3.

Saya telah melakukan 1 juta perkalian matriks dari vec4 dengan matriks 4x4.

lwjgl selesai dalam 18ms, jblas diperlukan sekitar 60ms.

(Saya berasumsi, bahwa pendekatan JNI tidak terlalu cocok untuk aplikasi cepat dari perkalian yang relatif kecil. Karena penerjemahan / pemetaan mungkin membutuhkan waktu lebih lama daripada pelaksanaan perkalian yang sebenarnya.)


1

Saya telah menemukan bahwa jika Anda membuat banyak Matriks dimensi tinggi, Anda dapat membuat Jama sekitar 20% lebih cepat jika Anda mengubahnya menggunakan array dimensi tunggal daripada array dua dimensi. Ini karena Java tidak mendukung array multi dimensi secara efisien. yaitu. itu menciptakan array array.

Colt sudah melakukan ini, tetapi saya telah menemukan ini lebih rumit dan lebih kuat daripada Jama yang dapat menjelaskan mengapa fungsi sederhana lebih lambat dengan Colt.

Jawabannya sangat tergantung pada apa yang Anda lakukan. Jama tidak mendukung sebagian kecil dari hal-hal yang dapat dilakukan Colt yang membuat lebih banyak perbedaan.



0

Ada banyak perpustakaan aljabar linier java yang tersedia secara bebas. http://www.ujmp.org/java-matrix/benchmark/ Sayangnya benchmark itu hanya memberi Anda info tentang multiplikasi matriks (dengan transposing tes tidak memungkinkan perpustakaan berbeda untuk mengeksploitasi fitur desain masing-masing).

Yang harus Anda perhatikan adalah bagaimana pustaka aljabar linier ini bekerja ketika diminta untuk menghitung berbagai dekomposisi matriks. http://ojalgo.org/matrix_compare.html


0

Matrix Tookits Java (MTJ) sudah disebutkan sebelumnya, tapi mungkin ada baiknya menyebutkan lagi untuk orang lain yang tersandung ke thread ini. Bagi mereka yang tertarik, sepertinya ada juga pembicaraan tentang meminta MTJ mengganti perpustakaan linalg di apache commons math 2.0 , meskipun saya tidak yakin bagaimana perkembangannya akhir-akhir ini.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.