Les performances de Java matrice bibliothèques de mathématiques?
Nous sommes le calcul de quelque chose dont l'exécution est liée par des opérations matricielles. (Quelques détails ci-dessous si vous êtes intéressé.) Cette expérience nous a amenés à la question suivante:
Ne folkloriques ont de l'expérience avec les performances des bibliothèques Java pour la matrice de mathématiques (par exemple, multiplier, inverse, etc.)? Par exemple:
J'ai cherché et rien trouvé.
Détails de notre système de comparaison de la vitesse:
Nous sommes à l'aide d'Intel FORTRAN (ifort (IFORT) 10.1 20070913). Nous avons ré-implémenté en Java (1.6) à l'aide d'Apache commons mathématiques 1.2 matrice de la fpo, et il convient à tous ses chiffres de précision. (Nous avons des raisons pour vouloir en Java.) (Java doubles, Fortran real*8). Fortran: 6 minutes, Java 33 minutes), de même machine. jvisualm profilage montre beaucoup de temps passé dans RealMatrixImpl.{getEntry,isValidCoordinate} (qui semblent avoir disparu d'inédits Apache commons mathématiques 2.0, mais le 2.0 n'est plus rapide). Fortran est l'aide de l'Atlas routines BLAS (dpotrf, etc.).
Évidemment, cela dépend de notre code dans chaque langue, mais nous pensons que la plupart du temps, c'est l'équivalent de la matrice des opérations.
Dans plusieurs autres calculs qui n'impliquent pas de bibliothèques, Java n'a pas été beaucoup plus lent, et parfois beaucoup plus rapide.
- La complexité de la matrice de mathématiques ops sont au moins O(n^3)... pire venir en pire, je suppose que vous pourriez de temps et de test...
- Pourquoi avez-vous besoin d'inverses? Pour presque toutes les applications, vous n'avez pas besoin du réel inverse. Le calcul de l'inverse est une mauvaise idée à cause de problèmes de stabilité.
- Oui, nous pourrions le temps. Je me demandais si d'autres l'avaient déjà fait. @Ying Xiao: Oui, inverses sont à éviter. Cependant, ce calcul semble la plus simple de l'utiliser. Voir en.wikipedia.org/wiki/....
- C'est faux, il y a des méthodes plus efficaces que O(n^3) à l'aide d'une division et de conquête de l'approche.
- Oui, O(n^log2(7)) est au moins possible. Il est illustré par de Strassen et est assez simple à mettre en œuvre. Il y a de mieux asymptotique des fois si, mais ils peuvent avoir infaisable grandes constantes.
- La plus rapide des performances natives est de JCublas. Si vous avez besoin rapide de l'algèbre linéaire, vous avez besoin de Gpu. JOCL avec clMath peut également travailler et être portables pour les Processeurs (et même multi-plate-forme de w/o recompiler), mais je n'ai pas testé.
Vous devez vous connecter pour publier un commentaire.
Juste pour ajouter mes 2 cents. Je l'ai comparée à certaines de ces bibliothèques. J'ai essayé de multiplier une matrice 3000 de 3000 de la matrice de doubles de lui-même. Les résultats sont comme suit.
À l'aide multithread ATLAS avec C/C++, Octave, Python et R, le temps était d'environ 4 secondes.
À l'aide de la Jama avec Java, le temps était de 50 secondes.
À l'aide de Colt et Parallèle Colt avec Java, le temps était de 150 secondes!
À l'aide de JBLAS avec Java, le temps était à nouveau autour de 4 secondes JBLAS utilise multithread ATLAS.
Donc pour moi il était clair que les bibliothèques Java de ne pas effectuer trop bien. Toutefois, si quelqu'un a un code en Java, alors la meilleure option est JBLAS. Jama, Colt et Parallèle Colt ne sont pas rapides.
netlib-java
)Je suis l'auteur de Java de la Matrice de Référence (JMatBench) et je vais vous donner mes pensées sur cette discussion.
Il y a de différence significative entre les bibliothèques Java et alors qu'il n'y a pas de gagnant clair dans l'ensemble des opérations, il y a quelques des chefs comme on peut le voir dans le derniers résultats (octobre 2013).
Si vous travaillez avec des "grands" matrices et peuvent utiliser des bibliothèques natives, puis le gagnant clair (3,5 x plus rapide) est MTJ avec système optimisé netlib. Si vous avez besoin d'un pur Java solution, alors MTJ, OjAlgo, EJML et En Parallèle Colt sont de bons choix. Pour les petites matrices EJML est le gagnant clair.
Les bibliothèques, je n'ai pas mentionner a montré des problèmes de performances ou manquantes principales caractéristiques.
Je suis l'auteur principal de jblas et tenais à préciser que j'ai publié la Version 1.0 à la fin de décembre 2009. J'ai beaucoup travaillé sur l'emballage, ce qui signifie que vous pouvez maintenant, il suffit de télécharger un "gros pot" de l'ATLAS et bibliothèques JNI pour Windows, Linux, Mac OS X, 32 et 64 bits (sauf pour Windows). De cette façon, vous obtiendrez des performances natives juste en ajoutant le fichier jar au classpath. Check it out à http://jblas.org!
J'ai juste comparé Apache Commons Mathématiques avec jlapack.
Test: décomposition en valeurs singulières d'un hasard de 1024x1024 de la matrice.
Machine: Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66 GHz, linux x64
Octave code: A=rand(1024); tic;[U,S,V]=svd(A);table des matières
Ma conclusion est que jlapack appelé à partir de JDK 1.7 est très proche du natif
binaire de la performance de lapack. J'ai utilisé le lapack binaire de la bibliothèque sont à venir avec des distro linux et a invoqué le dgesvd de routine afin d'obtenir le U,S et VT matrices ainsi. Tous les tests ont été fait à l'aide de double précision sur exactement la même matrice à chaque exécution (à l'exception d'Octave).
Avertissement - je ne suis pas un expert en algèbre linéaire, qui ne sont pas affiliés à l'une des bibliothèques ci-dessus et ce n'est pas une rigoureuse de référence.
C'est un "fait-maison" de test, comme j'étais intéressé de comparer l'augmentation de la performance de JDK 1.7 1.6 ainsi que les communes de mathématiques SVD à jlapack.
Jeigen https://github.com/hughperkins/jeigen
Un test rapide, par la multiplication de deux matrices denses, c'est à dire:
importation statique jeigen.MatrixUtil.*;
Résultats:
Je ne peux pas vraiment commenter sur les bibliothèques spécifiques, mais en principe il y a peu de raisons pour que de telles opérations pour être plus lent en Java. Hotspot généralement le genre de choses que vous attendez d'un compilateur à faire: il compile des opérations de calcul de base sur Java variables correspondant à des instructions machine (il utilise les instructions SSE, mais un seul par opération); accès aux éléments d'un tableau sont compilés pour utiliser "raw" instructions MOV comme vous le souhaitez; il prend des décisions sur la façon d'allouer les variables de registres quand il le peut; il re-commandes, instructions pour prendre avantage de l'architecture du processeur... Une exception possible est que comme je l'ai mentionné, Point d'accès uniquement effectuer une opération par l'ESS de l'enseignement; en principe, on pourrait avoir un fantastique optimisée de la matrice de la bibliothèque qui a effectué plusieurs opérations par l'instruction, bien que je ne sais pas si, par exemple, votre bibliothèque FORTRAN fait ou si une telle bibliothèque existe même. Si elle le fait, il n'y a actuellement aucun moyen pour Java (ou au moins, Hotspot) de rivaliser avec ça (mais vous pouvez bien sûr écrire votre propre bibliothèque native avec ces optimisations pour appeler à partir de Java).
Alors, que veut dire tout cela? Bien:
Un obstacle à la matrice des opérations est souvent la localité des données des problèmes qui surviennent lorsque vous avez besoin de parcourir ligne par ligne et colonne par colonne, par exemple, dans la matrice de la multiplication, depuis que vous avez à stocker les données dans un ordre qui optimise l'un ou l'autre. Mais si vous avez la main-d'écrire le code, vous pouvez parfois combiner des opérations afin d'optimiser la localité des données (par exemple, si vous êtes à la multiplication d'une matrice par sa transformation, vous pouvez transformer une colonne de la traversée en une suite de la traversée si vous écrivez une fonction dédiée à la place de la combinaison de deux fonctions de la bibliothèque). Comme d'habitude dans la vie, une bibliothèque vous donnera non-optimale d'échanges pour un développement plus rapide; vous devez décider combien de performance est pour vous.
Il y a un benchmark des différents de la matrice des packages en java disponible sur
http://code.google.com/p/java-matrix-benchmark/ pour quelques configurations matérielles différentes. Mais c'est pas un substitut pour faire votre propre indice de référence.
Performance va varier avec le type de matériel que vous avez (cpu, des carottes, de la mémoire, L1-3 cache, la vitesse du bus), la taille des matrices, et les algorithmes que vous souhaitez utiliser. Les différentes bibliothèques ont différents points de vue sur la simultanéité pour les différents algorithmes, donc il n'y a pas de réponse unique. Vous pouvez également trouver que les frais généraux de la traduction de la forme attendue par une bibliothèque native nie l'avantage de performance pour votre cas d'utilisation (certains des bibliothèques java ont des options plus flexibles quant à la matrice de stockage, qui peut être utilisé pour la poursuite de l'optimisation des performances).
En général, cependant, JAMA, Jampack et le POULAIN se fait vieux, et ne représentent pas l'état de la performance actuelle en Java disponible pour l'algèbre linéaire. Plus moderne de bibliothèques de rendre plus efficace l'utilisation de plusieurs cœurs cpu et les caches. JAMA est une implémentation de référence, et à peu près implémente manuel algorithmes avec peu d'égard à la performance. COLT et IBM Ninja ont été les premières bibliothèques java pour montrer que la performance a été possible en java, même si ils ont été à la traîne de 50% derrière bibliothèques natives.
Je suis l'auteur de la4j (Algèbre Linéaire pour Java) bibliothèque et voici mon point de vue. J'ai travaillé sur la4j pour 3 ans (la dernière version est la version 0.4.0 [01 Jun 2013]) et c'est seulement maintenant que je peux commencer à faire des performances d'analyse et optimisations depuis j'ai simplement recouvert du minimum requis fonctionnels. Donc, la4j n'est pas aussi rapide que je voulais, mais je suis dépenses beaucoup de mon temps à changer.
Je suis actuellement dans le milieu de portage de la nouvelle version de la4j à JMatBench plate-forme. J'espère que la nouvelle version va montrer de meilleures performances alors précédent puisqu'il y a plusieurs améliorations que j'ai faites dans la4j comme beaucoup plus rapide interne de la matrice de format, dangereux accesseurs et blocage rapide de l'algorithme pour la matrice de multiplications.
Nous avons utilisé COLT pour certains assez grand sérieux calculs financiers et ont été très heureux avec elle. Dans notre lourdement profilé code nous n'avons presque jamais eu à remplacer un COLT mise en œuvre avec l'un des nôtres.
Dans leurs propres tests (évidemment pas indépendante) je pense qu'ils prétendent à l'intérieur d'un facteur 2 de l'Intel main optimisée routines assembleur. Le truc à l'aide de ce bien est de s'assurer que vous comprenez leur philosophie de conception, et d'éviter étrangères allocation des objets.
Avez-vous pris un coup d'oeil à la Intel Math Kernel Library? Il prétend surpasser même ATLAS. MKL peut être Java par JNI wrappers.
Linalg code qui s'appuie fortement sur les Pentiums et plus tard par les transformateurs de vecteur de fonctions de calcul (en commençant par le MMX extensions, comme LAPACK et maintenant Atlas BLAS) n'est pas "superbement optimisé", mais tout simplement la norme de l'industrie. Pour reproduire cette performance en Java, vous allez avoir besoin des bibliothèques natives. J'ai eu le même problème que vous décrivez (principalement, pour être en mesure de calculer Choleski décompositions) et n'ai rien trouvé de vraiment efficace: Jama est Java pur, puisqu'il est censé être juste un modèle de référence et le kit pour les réalisateurs à suivre... qui n'est jamais arrivé. Vous savez Apache mathématiques de communes... Comme pour COLT, j'ai pas encore tester, mais il semble miser sur Ninja améliorations, dont la plupart ont été atteint par la construction d'un ad-hoc compilateur Java, donc je doute qu'il va aider.
À ce point, je pense que nous avons "juste" besoin d'un effort collectif pour construire un natif Jama mise en œuvre...
Bâtiment sur Varkhan post qui Pentium spécifiques du code natif feraient mieux:
jBLAS: Un alpha-stade de projet avec JNI wrappers pour Atlas: http://www.jblas.org.
MTJ: un Autre exemple de projet: http://code.google.com/p/matrix-toolkits-java/
Vous voudrez peut-être vérifier la jblas projet. C'est une relativement nouvelle bibliothèque Java qui utilise BLAS, LAPACK et de l'ATLAS pour la haute performance des opérations matricielles.
Le développeur a posté quelques repères dans lequel jblas vient favorablement contre MTJ et Colt.
Pour les applications graphiques 3d le lwjgl.util vecteur de mise en œuvre réalisé mentionnés ci-dessus jblas par un facteur d'environ 3.
J'ai fait 1 million de matrice de multiplications d'un vec4 avec une matrice 4x4.
lwjgl fini dans environ 18ms, jblas nécessaires sur les 60ms.
(Je suppose, que la JNI approche n'est pas très adapté pour une rapide application successive de relativement petites multiplications. Depuis la traduction/localisation peut prendre plus de temps que l'exécution réelle de la multiplication.)
Il y a aussi UJMP
Il ya beaucoup de différents librement disponible java algèbre linéaire bibliothèques. http://www.ujmp.org/java-matrix/benchmark/
Malheureusement, ce point de référence seulement vous donne les infos à propos de la multiplication de matrice (avec la transposition de l'essai ne permet pas les différentes bibliothèques à l'exploitation de leurs respectifs caractéristiques de conception).
Ce que vous devez regarder, c'est comment ces algèbre linéaire bibliothèques effectuer quand on lui demande de calculer les différentes décompositions de matrices.
http://ojalgo.org/matrix_compare.html
J'ai trouvé que si vous êtes la création d'un lot de grande dimensions des Matrices, vous pouvez faire Jama environ 20% plus rapide si vous changez d'utiliser une seule dimension tableau au lieu d'un tableau à deux dimensions. C'est parce que Java ne supporte pas le multi-dimensions des tableaux de manière aussi efficace. c'est à dire. il crée un tableau de tableaux.
Colt fait déjà, mais j'ai trouvé que c'est plus compliqué et plus puissant que Jama qui peut expliquer pourquoi les fonctions simples sont plus lents avec Colt.
La réponse dépend vraiment de ce que vous faites. Jama ne prend pas en charge une fraction des choses Colt pouvez faire qui font plus de différence.
Matrice Tookits Java (MTJ) a déjà été mentionné avant, mais peut-être qu'il vaut la peine de mentionner à nouveau pour quelqu'un d'autre d'achoppement sur ce fil. Pour ceux que cela intéresse, il semble que il ya aussi parler de MTJ remplacer le linalg de la bibliothèque dans le apache commons mathématiques 2.0, si je ne suis pas sûr de savoir comment c'est de progresser ces derniers temps.
Vous devez ajouter Apache Mahout à votre liste de courses.