Java matris matematik kütüphanelerinin performansı? [kapalı]


151

Çalışma zamanı matris işlemleriyle bağlı olan bir şeyi hesaplıyoruz. (İlgiliyse aşağıdaki bazı ayrıntılar.) Bu deneyim aşağıdaki soruyu yöneltti:

Halk, matris matematiği için Java kitaplıklarının performansıyla ilgili deneyime sahip mi (ör. Çarpma, ters vb.)? Örneğin:

Aradım ve hiçbir şey bulamadım.


Hız karşılaştırmamızın detayları:

Intel FORTRAN (ifort (IFORT) 10.1 20070913) kullanıyoruz. Apache commons math 1.2 matrix ops'u kullanarak Java'da (1.6) yeniden uyguladık ve tüm doğruluk basamaklarını kabul etti. (Java'da istemek için nedenlerimiz var.) (Java iki katına çıkar, Fortran real * 8). Fortran: 6 dakika, Java 33 dakika, aynı makine. jvisualm profili oluşturma RealMatrixImpl'de çok fazla zaman geçirdiğini gösterir. {getEntry, isValidCoordinate} (yayınlanmamış Apache commons math 2.0'da yok gibi görünüyor, ancak 2.0 daha hızlı değil). Fortran, Atlas BLAS rutinlerini (dpotrf vb.) Kullanıyor.

Açıkçası bu her dilde kodumuza bağlı olabilir, ancak çoğu zaman eşdeğer matris işlemlerinde olduğuna inanıyoruz.

Kütüphaneleri içermeyen diğer bazı hesaplamalarda, Java çok daha yavaş ve bazen daha hızlı olmamıştır.


Zor matris matematik ops en az O (n ^ 3) ... daha kötü daha kötüye gel, sanırım zaman ve test edebilirsin ...
Calyth

2
Neden tersine ihtiyacınız var? Hemen hemen tüm uygulamalar için gerçek tersine ihtiyacınız yoktur. İstikrar sorunları nedeniyle tersi hesaplamak kötü bir fikirdir.
Ying Xiao

1
@Calyth: Evet, zaman alabiliriz. Başkalarının zaten olup olmadığını merak ediyordum. @ Xiao: Evet, terslerden kaçınılmalıdır. Bununla birlikte, bu hesaplama bunu kullanarak en basit şekilde görünmektedir. Bkz. En.wikipedia.org/wiki/… .
dfrankow

2
@Calyth Bu yanlış, böl ve fethet yaklaşımını kullanan O (n ^ 3) yönteminden daha etkili yöntemler var.
starblue

1
En hızlı yerel performans JCublas'tan. Hızlı lineer cebire ihtiyacınız varsa, GPU'lara ihtiyacınız vardır. ClMath ile JOCL de çalışabilir ve CPU'lar için taşınabilir olabilir (ve yeniden derleme olmadan çok platformlu), ancak test etmedim.
Aleksandr Dubinsky

Yanıtlar:


98

Sadece 2 sentimi eklemek için. Bu kütüphanelerin bazılarını karşılaştırdım. Kendisi ile 3000 ile 3000 arasında iki katına çıkan bir matrisi matrisle çarpmaya çalıştım. Sonuçlar aşağıdaki gibidir.

C / C ++, Octave, Python ve R ile çok iş parçacıklı ATLAS kullanıldığında, süre yaklaşık 4 saniye idi.

Jama ile Java kullanarak, geçen süre 50 saniyeydi.

Java ile Colt ve Paralel Colt kullanarak, zaman 150 saniye oldu!

JBLAS Java ile kullanıldığında, JBLAS çok iş parçacıklı ATLAS kullandığı için geçen süre tekrar 4 saniyeydi.

Bu yüzden benim için Java kütüphanelerinin çok iyi performans göstermediği açıktı. Ancak birisinin Java'da kodlaması gerekiyorsa, en iyi seçenek JBLAS'tır. Jama, Colt ve Paralel Colt hızlı değildir.


3
Sanırım çok çekirdekli bir makine kullanıyordunuz, bu yüzden bu sonuçlar kütüphanenin çok çekirdekli kullanılıp kullanılmamasından ciddi şekilde etkileniyor mu? Bazı amaçlar için, örneğin, mpi veya hadoop vb . Kullanılarak paralelleme yapıldığında, mpi / hadoop uygulaması şeyleri paralelleştirmeye özen gösterdiğinden , önemli zaman aslında tek çekirdekli süredir. (En azından benim için jblas, jama'dan yaklaşık 2.5 daha hızlı, jama'dan 10 kat daha hızlı değil.)
Hugh Perkins

17
Netlib-java'nın v1.0 sürümünü piyasaya sundum ... performans eşittir (ve bazen de Fortran kodunu aşar) ve kullanıcı kodunda herhangi bir değişiklik yapmadan makine için optimize edilmiş yerlileri kullanabilir. Lütfen düşük seviyeli doğrusal cebir kütüphaneleri ararken bunu göz önünde bulundurun. Ben de korumak Mtj netlib-java kullanan,. Scala'da Breeze kullanın (aynı zamanda destekliyor netlib-java)
fommil

4
ND4j ve java kullanarak - nispeten eski dizüstü bilgisayarım önerilen çarpımı 219 milisaniyede tamamlıyor. Python + numpy 349 milis içinde tamamlarken
bennyl

2
Ve sadece nd4j kullanımı ile ilgili son yorumuma eklemek için, arka uç olarak yerel platformu kullandım, cuda platformu kullanırsam yaklaşık 1 milisaniye sürer
bennyl

Testler için kodunuzu bir yerde yayınladınız mı?
bruziuz

108

Java Matrix Benchmark'ın ( JMatBench ) yazarıyım ve bu tartışma hakkındaki düşüncelerimi vereceğim.

Java kütüphaneleri arasında önemli bir fark vardır ve tüm operasyonlar arasında açık bir kazanan olmasa da, en son performans sonuçlarında görülebileceği gibi birkaç açık lider vardır (Ekim 2013).

Eğer "büyük" matrisleri ile çalışıyoruz ve (daha hızlı 3.5x hakkında) yerel kütüphaneleri, daha sonra kesin kazanan kullanabiliyorsa olan MTJ ile sistem optimize NETLIB . Saf bir Java çözümüne ihtiyacınız varsa , MTJ , OjAlgo , EJML ve Paralel Colt iyi seçimlerdir. Küçük matrisler için EJML açık kazanır.

Bahsetmediğim kütüphanelerde önemli performans sorunları ya da önemli özellikler eksikti.


6
Ben sadece kıstasınız gerçekten kullanışlı olduğunu söyleyebilirim düşündüm! Zaman ayırdığınız için teşekkürler.
hohonuuli

1
JBLAS, Eylül '13'ten itibaren SVD'yi destekliyor gibi görünüyor: mikiobraun.github.io/jblas/javadoc/org/jblas/…
Leopd

harika iş, çok teşekkürler.
webpat

Değerlendirdiğiniz, ancak sonuçlarını yayınlamadığınız kütüphanelerin bir listesi ve her birinin nedenleri var mı?
Kevin Krumwiede

1
MTJ terk edilmiş görünüyor: depo arşivlendi ve son taahhüt 2016'da yapıldı.
Danila Piatov

51

Ben jblas'ın ana yazarıyım ve Aralık 2009'un sonlarında Sürüm 1.0'ı yayınladığımı belirtmek istedim. Ambalaj üzerinde çok çalıştım, yani artık ATLAS ve JNI kütüphaneleriyle bir "yağ kavanozu" indirebilirsiniz. Windows, Linux, Mac OS X, 32 ve 64 bit için (Windows hariç). Bu şekilde jar dosyasını sınıf yolunuza ekleyerek yerel performansı elde edersiniz. Http://jblas.org adresinden göz atın !


2
çalışmalarından esinlenerek, netlib-java ;-)
fommil'da

2
Haha, ben de, jeigen için :-)
Hugh Perkins

JogAmp da aynısını yapar, bkz. Jogamp-fat.jar. İyi fikir :)
gouessej

8

Belirli kütüphaneler hakkında gerçekten yorum yapamam, ancak prensip olarak bu tür işlemlerin Java'da daha yavaş olması için çok az neden var. Hotspot genellikle bir derleyicinin yapmasını beklediğiniz şeyleri yapar: Java değişkenleri üzerindeki temel matematik işlemlerini karşılık gelen makine talimatlarına derler (SSE komutlarını kullanır, ancak her işlem için yalnızca bir tane); bir dizinin elemanlarına erişim, beklediğiniz gibi "ham" MOV komutlarını kullanmak üzere derlenir; Değişkenleri kayıtlara nasıl ayırabileceğine karar verir; işlemci mimarisinden faydalanmak için talimatları yeniden sipariş eder ... Olası bir istisna, Hotspot'un SSE talimatı başına yalnızca bir işlem gerçekleştireceğidir; prensipte, talimat başına birden çok işlem gerçekleştiren fevkalade optimize edilmiş bir matris kütüphanesine sahip olabilirsiniz, ancak t Örneğin, belirli FORTRAN kitaplığınızın bunu yapıp yapmadığını veya böyle bir kitaplığın var olup olmadığını bilmiyor. Eğer öyleyse, şu anda Java'nın (veya en azından Hotspot) bununla rekabet etmesinin bir yolu yoktur (yine de Java'dan aramak için bu optimizasyonlarla kendi yerel kütüphanenizi yazabilirsiniz).

Peki bütün bunlar ne anlama geliyor? İyi:

  • prensip olarak, daha iyi performans gösteren bir kütüphane için avlanmaya değer, ancak ne yazık ki bir tane tavsiye edemiyorum
  • performans sizin için gerçekten kritikse, sadece kendi matris işlemlerinizi kodlamayı düşünürüm, çünkü daha sonra bir kütüphanenin genel olarak yapamayacağı veya kullandığınız belirli bir kütüphanenin yapmadığı belirli optimizasyonları gerçekleştirebilirsiniz ( çok işlemcili makine, kütüphanenin gerçekten çok iş parçacıklı olup olmadığını öğrenin)

Matris işlemlerinde bir engel, verileri bir veya diğerini optimize eden bir sırayla saklamak zorunda olduğunuz için, örneğin matris çarpımında hem satır hem de sütun sütun geçmeniz gerektiğinde ortaya çıkan veri konum sorunlarıdır. Ancak kodu el ile yazarsanız, bazen veri konumunu optimize etmek için işlemleri birleştirebilirsiniz (örneğin, bir matrisi dönüştürmesiyle çarpıyorsanız, birleştirme yerine özel bir işlev yazarsanız bir sütun geçişini satır geçişine dönüştürebilirsiniz iki kütüphane işlevi). Hayatta her zaman olduğu gibi, bir kütüphane size daha hızlı gelişim karşılığında optimum olmayan bir performans verecektir; performansın sizin için ne kadar önemli olduğuna karar vermeniz gerekir.


8

Apache Commons Math'ı jlapack ile karşılaştırdım.

Test: rastgele bir 1024x1024 matrisinin tekil değer ayrışması.

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

Oktav kodu: A = rand (1024); tlc [U, S, V] = SVD (A) TOC

sonuç yürütme süresi
-------------------------------------------------- -------
Oktav 36.34 saniye

JDK 1.7u2 64 bit
    jlapack dgesvd 37.78 saniye
    apache commons matematik SVD 42.24 saniye


JDK 1.6u30 64 bit
    jlapack dgesvd 48.68 saniye
    apache commons matematik SVD 50.59 saniye

Yerel rutinler
Lapack * C'den çağrıldı: 37,64 sn
Intel MKL 6.89 saniye (!)

Sonuç olarak, JDK 1.7'den çağrılan jlapack, lapack'in yerel ikili performansına çok yakın. Linux dağıtım ile gelen lapack ikili kütüphanesini kullandım ve dgesvd rutinini U, S ve VT matrislerini almak için çağırdım. Tüm testler, her çalışmada tam olarak aynı matriste (Octave hariç) çift kesinlik kullanılarak yapıldı.

Feragatname - Lineer cebir konusunda uzman değilim, yukarıdaki kütüphanelerin hiçbirine bağlı değilim ve bu çok sıkı bir kriter değil. JDK 1.7 ile 1.6 arasındaki performans artışını ve matematik SVD'sini jlapack ile karşılaştırmakla ilgilendiğim için 'ev yapımı' bir test.


8

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

  • mevcut en hızlı ücretsiz C ++ kütüphanelerinden biri olan Eigen C ++ kütüphanesini sarar http://eigen.tuxfamily.org
  • nispeten kısa sözdizimi, örneğin 'mmul', 'sub'
  • hem yoğun hem de seyrek matrisleri işler

İki yoğun matrisi çarparak hızlı bir test, yani:

statik 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();

Sonuçlar:

Jama: 4090 ms
Jblas: 1594 ms
Ojalgo: 2381 ms (using two threads)
Jeigen: 2514 ms
  • Jama ile karşılaştırıldığında, her şey daha hızlıdır:
  • Jblas ile karşılaştırıldığında, Jeigen o kadar hızlı değildir, ancak seyrek matrisleri ele alır.
  • Ojalgo ile karşılaştırıldığında, Jeigen yaklaşık aynı süreyi alır, ancak sadece bir çekirdek kullanır, bu nedenle Jeigen toplam CPU'nun yarısını kullanır. Jeigen'in ters sözdizimi vardır, yani 'multiplRight'a karşı' mmul '

Jeigen harika görünüyor! Son zamanlarda çok büyük seyrek matrisleri çözmek için JNI ve bir DLL kullanarak Java Eigen uyguladı. DLL sürümüm, testlerim için (8000x8000 matrisin üzerinde) paralel colt daha hızlıdır. Keşke Jeigen hakkında bilgi sahibi olsaydım!
Z bozonu

6

Java'da birkaç farklı donanım yapılandırması için http://code.google.com/p/java-matrix-benchmark/ adresinde bulunan çeşitli matris paketlerinin bir karşılaştırması vardır . Ama kendi kriterlerinizi yapmanın yerini tutmaz.

Performans, sahip olduğunuz donanım türüne (cpu, çekirdekler, bellek, L1-3 önbellek, veri yolu hızı), matrislerin boyutuna ve kullanmak istediğiniz algoritmalara göre değişecektir. Farklı kütüphanelerin farklı algoritmalar için farklı eşzamanlılıkları vardır, bu yüzden tek bir cevap yoktur. Ayrıca, yerel bir kütüphane tarafından beklenen forma çevrilme yükünün kullanım durumunuz için performans avantajını olumsuz yönde etkilediğini görebilirsiniz (bazı java kütüphanelerinde, daha fazla performans optimizasyonu için kullanılabilen matris depolama ile ilgili daha esnek seçenekler bulunur).

Genellikle, JAMA, Jampack ve COLT yaşlanıyor ve doğrusal cebir için Java'da mevcut performansın durumunu temsil etmiyor. Daha modern kütüphaneler birden fazla çekirdeği ve cpu önbelleklerini daha etkili bir şekilde kullanır. JAMA bir referans uygulamasıydı ve ders kitabı algoritmalarını performans açısından çok az dikkate alarak uyguluyor. COLT ve IBM Ninja, yerel kütüphanelerin% 50 gerisinde kalsalar bile, java'da performansın mümkün olduğunu gösteren ilk java kütüphaneleriydi.


4

Ben la4j (Java için Linear Algebra) kütüphanesinin yazarıyım ve işte burada benim açımdan. 3 yıldır la4j üzerinde çalışıyorum (en son sürüm 0.4.0 [01 Haz 2013]) ve sadece şimdi minimum gerekli işlevselliği kapsadığım için performans analizi ve optimizasyon yapmaya başlayabilirim. Yani, la4j istediğim kadar hızlı değil ama değiştirmek için zamanımın çoğunu harcıyorum.

Şu anda la4j'nin yeni sürümünü JMatBench platformuna taşımanın ortasındayım . Umarım yeni sürüm bir öncekinden daha iyi performans gösterir, çünkü la4j'de yaptığım çok daha hızlı dahili matris formatı, güvensiz erişimciler ve matris çarpımları için hızlı engelleme algoritması gibi birkaç gelişme var.


1
Hayır - la4j gerçekten rakipsiz. Bkz. Code.google.com/p/java-matrix-benchmark
Christopher Manning

Çok değişti. Cevabınızdan bu yana kütüphanenin iki versiyonunu yayınladım. Mevcut sürüm 0.4.0'dır. Ve sadece uçuyor.
Vladimir Kostyukov

3

Pentium'lara ve daha sonraki işlemcilerin vektör hesaplama yeteneklerine (LAPACK ve şimdi Atlas BLAS gibi MMX uzantılarından başlayarak) dayanan Linalg kodu "fevkalade optimize edilmiş" değil, sadece endüstri standardıdır. Java'daki bu performansı çoğaltmak için yerel kütüphanelere ihtiyacınız olacak. Açıkladığınızla aynı performans problemine sahiptim (esas olarak, Choleski ayrışmalarını hesaplayabilmek için) ve gerçekten etkili bir şey bulamadım: Jama, saf Java'dır, çünkü uygulayıcıların takip etmesi için sadece bir şablon ve referans kiti olması gerekiyordu. .. hiç olmadı. Apache matematik ortaklarını biliyorsunuz ... COLT'a gelince, hala test etmem gerekiyor, ancak çoğu Ad-hoc Java derleyicisi oluşturarak ulaşılan Ninja iyileştirmelerine büyük ölçüde güveniyor gibi görünüyor, bu yüzden yardımcı olacağından şüpheliyim. Bu noktada, bence biz


İyi bir nokta! Atlas için JNI sarmalayıcıları olan alfa aşamalı bir proje: jblas.org . Yazarın blog yazısı: mikiobraun.blogspot.com/2008/10/…
dfrankow

3

Bazı oldukça büyük ciddi finansal hesaplamalar için COLT kullandık ve bundan çok memnun kaldık. Yoğun profilli kodumuzda, neredeyse hiç COLT uygulamasını kendimizinkilerle değiştirmek zorunda kalmadık.

Kendi testlerinde (açıkça bağımsız değil), Intel'in elle optimize edilmiş montajcı rutinlerinin 2 faktörü içinde olduğunu iddia ediyorlar. İyi kullanmanın hilesi, tasarım felsefelerini anladığınızdan ve yabancı nesne tahsisinden kaçındığınızdan emin olmaktır.


3

Eğer bir göz uyguladınız mı Intel Math Kernel Library ? Hatta daha iyi performans iddia ATLAS . MKL, Java'da JNI sarmalayıcıları ile kullanılabilir.


2
Bizde var. a) Lisansı Atlas'tan daha kısıtlayıcıdır (bu nedenle tüm bilgisayarlarımızı kullanamayız); b) Java değil (ve dediğim gibi Java'da olmak istemek için nedenlerimiz var).
dfrankow

yani, bu Java kütüphaneleri ile ilgili sorumun cevabı değil (ama bunu aşağılamak için itibarım yok).
dfrankow

@dfrankow: Java'da kullanma konusundaki endişenizi gidermek için cevabımı güncelledim.
Zach Scrivena

1
+1, Aradığınız hız, bu gitmek için bir yol gibi görünüyor
Gab Royer

2
Son bağlantı koptu.
gouessej


2

Jblas projesine göz atmak isteyebilirsiniz . Yüksek performanslı matris işlemleri için BLAS, LAPACK ve ATLAS kullanan nispeten yeni bir Java kütüphanesidir.

Geliştirici, jblas'ın MTJ ve Colt'a karşı olumlu bir şekilde çıktığı bazı kriterler yayınladı .


2

3 boyutlu grafik uygulamaları için, yukarıda belirtilen jblasların yaklaşık 3'lük bir faktörle gerçekleştirildiği lwjgl.util vektör uygulaması.

4x4 matrisli bir vec4'ün 1 milyon matris çarpımını yaptım.

lwjgl yaklaşık 18ms bitmiş, jblas yaklaşık 60ms gerekli.

(JNI yaklaşımının nispeten küçük çarpmaların hızlı bir şekilde ardışık uygulanması için çok uygun olmadığını varsayıyorum. Çünkü çeviri / eşleme çarpmanın fiili yürütülmesinden daha fazla zaman alabilir.)


1

Çok yüksek boyutlu Matrisler oluşturuyorsanız, iki boyutlu bir dizi yerine tek boyutlu bir dizi kullanmak için değiştirirseniz Jama'i yaklaşık% 20 daha hızlı yapabileceğinizi buldum. Bunun nedeni Java'nın çok boyutlu dizileri verimli bir şekilde desteklememesidir. yani. bir dizi dizi oluşturur.

Colt bunu zaten yapıyor, ancak Jama'den daha karmaşık ve daha güçlü olduğunu gördüm, bu da Colt ile basit fonksiyonların neden daha yavaş olduğunu açıklayabilir.

Cevap gerçekten yaptığınıza bağlıdır. Jama, Colt'un yapabileceği şeylerin bir kısmını desteklemiyor ve bu da daha fazla fark yaratıyor.



0

Birçok farklı serbestçe kullanılabilen java lineer cebir kütüphanesi vardır. http://www.ujmp.org/java-matrix/benchmark/ Maalesef bu kıyaslama size sadece matris çarpımı hakkında bilgi veriyor (testi aktarmakla farklı kütüphanelerin ilgili tasarım özelliklerinden yararlanmasına izin vermiyor).

Bakmanız gereken şey, bu lineer cebir kütüphanelerinin, çeşitli matris ayrışımlarını hesaplamaları istendiğinde nasıl performans gösterdikleri. http://ojalgo.org/matrix_compare.html


0

Matrix Tookits Java (MTJ) daha önce de belirtilmişti, ancak belki de bu konuya tökezleyen herkes için tekrar bahsetmeye değer. İlgilenenler için, MTJ'nin apache commons math 2.0'daki linalg kütüphanesinin yerini almasından bahsetmek gibi görünüyor , ancak son zamanlarda nasıl ilerlediğinden emin değilim.


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.