处理Java中的大型数据结构

时间:2009-03-16 12:42:35

标签: java memory matrix

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

9 个答案:

答案 0 :(得分:8)

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

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

有许多众所周知的方法可以并行化矩阵乘法(基本上可以将各种大小的子矩阵相乘,然后将结果组合在一起)和移位布局,以便通过组织{{{}周围的数据来使访问模式具有合理的缓存局部性。 3}}而不是行/列安排。您当然希望查看经典的space-filling curves接口和设计,LAPACKIntel's MKL作为调整到特定现代硬件的BLAS功能的实现,之后您就是可能冒险进入未开发的领域: - )

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

考虑使用像http://hsqldb.org/

这样的内存数据库

答案 3 :(得分:2)

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

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

查看hadoop

答案 7 :(得分:1)

尝试使用Memory Mapped File将所有数据存储在外部文件中,然后通过FileChannel对象访问它。

查看this article,了解MMF的简要介绍。

答案 8 :(得分:0)