处理Java中的大型数据结构

我正在开发一个需要处理非常大的矩阵的Java应用程序。 例如,乘以两个1000万* 1000万个矩阵! 当然,即使存储这些矩阵中的一个,Java堆也没有足够的空间。 我该怎么办? 我应该使用数据库来存储我的矩阵并将每个所需的部分带入内存并将它们一个接一个地加倍吗?

首先,1000万x 1000万的矩阵非常庞大。 假设每个单元都有双打而且没有存储过载,这些东西中的每一个都将达到800太字节。 只需从主存储器读取每个单元格(如果它在某种程度上神奇地适合那里,显然没有发生),需要几天时间。 从任何类似的合理SAN(我们将它放在10GbE上)这样做更有可能是几个月。 并且矩阵乘法没有O(n)复杂度 – 正常方法是O(n ^ 3)。 所以…你没有使用内存映射文件,公共数据库或任何类似的东西。

执行此类操作的代码将在缓存效率上生存或死亡,其中“缓存”包括充分利用主内存,本地磁盘驱动器。 由于任何存储接口都拥有超过800 TB的矩阵必然会成为某种类型的SAN,因此您几乎肯定会涉及多台服务器读取和处理它的不同部分。

有许多众所周知的方法可以并行化矩阵乘法(基本上可以将各种大小的子矩阵相乘,然后将结果组合在一起)和移位布局,以便通过在空间填充曲线周围组织数据来使访问模式具有合理的缓存局部性行/列安排。 你肯定会想要看看经典的LAPACK接口和设计, 英特尔的MKL , GotoBLAS作为调整到特定现代硬件的BLASfunction的实现,之后你可能冒险进入未开发的领域:-)

如果天真地执行矩阵乘法的复杂性是O(n ^ 3),但确实存在更有效的算法。 无论如何,对于一个1000万* 1000万的矩阵,这将花费很长时间,你可能会遇到相同的堆问题,但具有递归性。

如果您正在进行复杂的数学运算,您可以在本文中找到帮助您的工具。

考虑使用像http://hsqldb.org/这样的内存数据库

由于这是一个如此巨大的计算,我认为你将遇到性能问题以及存储问题。 所以我会考虑并行化这个问题,并获得多个机器/核心来处理数据子集。

幸运的是,矩阵乘法解决方案会自然地分解。 但我会关注某种forms的网格或分布式计算解决方案。

使用适用于您的数据的任何稀疏矩阵算法。 (假设您没有2.4 PB的磁盘空间来容纳3个10 ^ 8平方的非稀疏矩阵的双精度数,更不用说内存数据库的那么多RAM – 只有Blue Gene / Q’有’ 1.6 PB。)

好吧,如果您被迫使用Java并且无法编写处理此问题的代码作为本机方法(也就是说,通过告诉Java调用某些C代码)那么最有效的做法就是使用简单的方法二进制文件。 在这种情况下,我会远离数据库,因为它们比直接文件访问慢,并且您不需要它们提供的function。

看看hadoop 。

通过将所有数据存储在外部文件中并通过FileChannel对象访问它来尝试使用内存映射文件 。

查看这篇文章 ,了解MMF的简要介绍。