我正在编写一个关于图像处理的程序。我需要存储一个大小为 480 000 列和 480 000 行的 int 方阵。有什么想法我该怎么做?
5 回答
不要使用 480,000 x 480,000 矩阵。
拥有这个完整矩阵(假设它不是稀疏的)的唯一原因是随机访问(即能够随时访问任何元素)。即使您能以某种方式实现这一点(存储 0.9Tb),数据访问也会非常慢(尤其是在将其映射到文件时),从而使您的算法效率低下。
相反,想办法重写你的算法,这样它就不需要在任何时候随机访问整个矩阵,但可能只需要你在需要时创建(然后删除)的一小部分,或减少存储这么多数据的需要的任何其他方式。
高性能不仅仅是减少计算量,关键还在于减少随机数据访问。
您可以将其存储在一个文件中,并将您需要的矩阵部分映射到内存中。参见例如http://en.wikipedia.org/wiki/Memory-mapped_file
如果您需要同时处理整个矩阵,并且大多数矩阵元素将是空白的,那么您应该考虑使用某种稀疏矩阵数据结构。许多线性代数库支持稀疏矩阵(Boost.uBlas、Eigen等),以及一些图像处理库(OpenCV等)。
这取决于矩阵将具有的特性。
它会有很多0吗?如果是这样,您可以使用不存储 0 的稀疏矩阵实现。
如果它是带矩阵,您可以只存储对角带。
您将不得不查看矩阵属性并查看可以节省内存的位置。如果您找不到任何允许此类优化的属性,则必须将其存储在文件中。
如果它是一个稀疏矩阵并且您需要对其进行一些线性代数,我会使用一些科学的线性代数库,如Trilinos(使用 Epetra 或 Tpetra 包)或Hypre。这些是高度并行的库(如果您可以并行运行代码,那就太好了)。我从来没有使用过 Hypre(尽管我听说它的性能比 Trilinos 好),所以我不能告诉你任何关于它的事情。Trilinos 是一个巨大(我会说太大)的库,大约有 50-60 个包,而且学习起来并不容易;但是如果你必须处理巨大的矩阵,那么依赖一些经过良好测试和开发的 TPL 是有意义的。对于矩阵存储,Epetra/Tpetra 是 Trilinos 中要研究的软件包。