我有一个来自特征库的稀疏矩阵,定义为:
Eigen::SparseMatrix<float> MyMatrix(2**n, 2**n).
字符串
此外,我使用的功能储备:
MyMatrix.reserve(Eigen::VectorXi::Constant(2**n, n+1));
型
这个矩阵每列有n+1个非零数字,它有2^n列
我想要这个对象实际占用的字节数。
如果我用途:
MyMatrix.size()
型
它给出n_rows*n_columns。
我肯定这不是存储的实际大小,因为我检查了计算机的内存。
例如,我可以用这种方式在我的计算机上创建一个2^25 * 2^25的浮点数稀疏矩阵,它应该占用~ 10^15字节,这是根本不可能的。
如果我写
sizeof(MyMatrix)
型
它给出72,无论我使用哪个n。它可能与类本身有关,而不是实际保存在其中的对象
更新2:
这是计算其大小的正确方法:
它是每个保留(或使用)元素一个float和一个int加上每列两个int加上sizeof(Matrix)固定开销
1条答案
按热度按时间fivyi3re1#
正如在评论中所讨论的,这里我解释稀疏矩阵格式
您调用
reserve()
,因此特定的子格式是 uncompressed。2**25 * 26 * 4 byte
)2**25 * 4 byte
)中的起始偏移量这使得
(2 * 2**25 * 26 * 4 + 2 * 2**25 * 4) / 1024**3
= 6.75 GiB我们来测试一下
字符串
这将打印:
型
如您所见,四个mmmap分配,总大小为7,247,773,696字节;即6.75 GiB。
这将在内存较少的笔记本电脑上工作的原因是,您还没有使用该内存。内存被Map,但没有初始化,因此操作系统将其全部Map到它为此目的而拥有的单个零页。参见例如Allocating more memory than there exists using malloc
范围关注点
需要注意的一点是,这种格式使用简单的
int
来表示非零元素的数组偏移量。这意味着非零(和保留元素)的总数必须保持在2**31-1
(有符号int
范围)以下。使用2**25 * 26
元素,您已经接近2**30
元素。除非你知道这是绝对的上限,不考虑增长,否则我建议你将格式改为
Eigen::SparseMatrix<float, Eigen::ColMajor, Eigen::Index>
,使用Eigen::Index
,也就是std::ptrdiff_t
,而不是int
。这将使内存使用量增加到大约10.25 GiB,但它将消除所有关于潜在整数溢出的担忧。