2009-03-16 6 views
7

Je travaille sur une application Java qui nécessite de travailler sur de très grandes matrices. Par exemple en multipliant deux 10 millions * 10 millions de matrices! Bien sûr, le tas Java n'a pas assez d'espace même pour stocker une de ces matrices. Que dois-je faire? Devrais-je utiliser des bases de données pour stocker mes matrices et mettre en mémoire toutes les parties nécessaires et les multiplier les unes après les autres?Gérer une grande structure de données en Java

+1

Est la matrice éparpillée par hasard? – TrayMan

+0

oui. ça peut être dans beaucoup de cas. mais nous ne pouvons pas être sûrs. – user78564

+0

Qu'essayez-vous d'accomplir? Très probablement ce n'est pas la bonne façon de le faire. – starblue

Répondre

2

envisager d'utiliser un db mémoire comme http://hsqldb.org/

+0

Ceci est une base de données relationnelle. Tu veux dire que je peux utiliser n'importe quel RDB pour ça ... par exemple MySQL? Est-il efficace d'utiliser une base de données? Je veux dire qu'il y a une meilleure solution (en utilisant l'espace disque ou ...). – user78564

+0

Je dirais DB "intégré", car HSQLDB peut faire beaucoup plus que de simples bases de données en mémoire. –

+0

@unknown: oui, un RDB est probablement une bonne idée pour cela, car il est conçu pour gérer des quantités massives de données. En fonction de vos besoins exacts, vous pourriez avoir besoin de logiciels plus spécialisés, mais d'après ce que vous avez écrit, je proposerais une base de données relationnelle. –

1

Eh bien, si vous êtes obligé d'utiliser Java et ne peut pas écrire le code qui traite de ces méthodes comme natives (qui est, en racontant Java d'appeler un code C à la place) alors la chose la plus efficace à faire serait d'utiliser un simple fichier binaire. Je resterais loin des bases de données dans ce cas parce qu'ils sont plus lents que l'accès direct aux fichiers et que vous n'avez pas besoin des fonctionnalités qu'ils offrent.

+0

je vois. Je vous remercie. Je pense que cela fonctionne pour mon application :) – user78564

+0

en utilisant un db en mémoire ne serait pas lent ... – Tobias

3

La complexité de la multiplication matricielle, si elle est effectuée naïvement, est O (n^3), mais des algorithmes plus efficaces existent. Quoi qu'il en soit, pour une matrice de 10 millions * 10 millions, cela va prendre beaucoup de temps et vous risquez de faire face au même problème, mais avec une récursivité.

Si vous êtes dans les mathématiques complexes, vous pouvez trouver un outil pour vous aider dans this article.

2

Étant donné que ce calcul est énorme, je pense que vous allez rencontrer des problèmes de performance à côté de vos problèmes de stockage. Donc, je chercherais à paralléliser ce problème et à obtenir des machines/cœurs multiples pour traiter un sous-ensemble de données.

Heureusement, une solution de multiplication matricielle se décomposera naturellement. Mais je regarderais une forme de grille ou une solution informatique distribuée.

2

Utilisez l'algorithme de matrice simple appliqué à vos données. (en supposant que vous n'avez pas 2.4 PB d'espace disque pour contenir 3 matrices non doubles de 10^8 carrés de doubles, et encore moins de RAM pour une base de données en mémoire - Blue Gene/Q 'only' a 1.6 PB.)

1

Essayez d'utiliser Memory Mapped File en stockant toutes vos données dans un fichier externe et d'y accéder via l'objet FileChannel.

Consultez la section this article pour une brève présentation de MMF.

8

Tout d'abord, une matrice de 10 millions x 10 millions est simplement énorme. En supposant des doublons pour chaque cellule et aucune surcharge de stockage, chacune de ces choses va être de 800 téraoctets. Il suffit de lire chaque cellule une fois de plus dans la mémoire principale (si cela se produit magiquement, ce qui ne se produit manifestement pas), cela prendrait des jours. Le faire à partir de n'importe quel type de SAN plausible (nous le mettrons sur 10GbE) est plus susceptible d'être des mois. Et aucune multiplication matricielle n'a une complexité O (n) - les approches normales sont O (n^3). Donc ... vous ne le faites pas avec des fichiers mappés en mémoire, des bases de données communes ou quoi que ce soit de ce genre. Code faisant quelque chose comme ceci va vivre ou mourir sur l'efficacité du cache, où "cache" comprend une bonne utilisation de la mémoire principale, les lecteurs de disque locaux. Étant donné que toute interface de stockage contenant plus d'une matrice de 800 téraoctets est forcément un SAN, il est presque certain que plusieurs serveurs lisent et travaillent sur différentes parties de celle-ci.Il existe de nombreux moyens bien connus pour paralléliser la multiplication matricielle (essentiellement multiplier les sous-matrices de différentes tailles et ensuite combiner les résultats), et déplacer la disposition de sorte que les modèles d'accès aient une localisation de cache raisonnable en organisant les données autour de space-filling curves au lieu des arrangements de rangée/colonne. Vous allez certainement vouloir regarder les interfaces classiques LAPACK et la conception, Intel's MKL, GotoBLAS comme les mises en œuvre des fonctions BLAS accordées à un matériel moderne spécifique, et après que vous vous aventurez probablement en territoire inexploré :-)

Questions connexes