为什么 PETSc 矩阵内存分配对性能有如此大的提升?

计算科学 宠物 效率 内存管理
2021-11-28 04:10:02

语境

在 Portable, Extensible Toolkit for Scientific Computing (PETSc) 中,用户经常创建矩阵和向量。然后将这些对象用作其他例程(如迭代求解器)的输入。

PETSc通过提供对角子矩阵和非对角子矩阵中非零条目的数量来提供预分配矩阵内存的例程。

MATLAB 有一些有用的文章来说明为什么预分配会有所帮助——例如,它消除了每次将元素添加到向量时重新分配内存的需要。

为什么 PETSc 中的内存预分配有这么大的帮助?当我告诉 PETSc 我的矩阵中非零的数量时到底发生了什么,与我不预分配时相比如何?

编辑

我在这个 powerpoint中找到了关于预分配如何与 AIJ 格式相关的部分答案。它说 PETSc 稀疏矩阵是动态对象,可以动态添加非零值。但是这种“即时”方法可能会导致额外的复制和重新分配等。我想这是我想要的答案,但更多细节会很棒。

1个回答

警告:这个答案只是给出一个简短的概述,对于真正的细节,一个不会出错的来源是源代码

核心矩阵 AIJ 格式与称为压缩稀疏行(CSR) 或耶鲁格式的格式基本相同。这会将稀疏矩阵存储为列表(通常具体实现为数组),A, 非零条目中,按(行索引)之类的键排序×(列数)+(列索引),以及一个列表,I, 中的索引A每行开始的位置,以及另一个列表,J,包含每个条目的列索引J. 这种格式可以快速拉出单独的行A, 并且适用于列向量的右乘。另一方面,这使得添加一个随机的新条目可能会很昂贵,因为这意味着将一个条目插入到列表的中间,这可能意味着重新分配一个新的内存块并复制你两侧的现有值重新插入。

根据代码,看起来在没有预分配的情况下使用 PETSc 会在其猜测中插入一些填充空间AJ,并存储一个附加列表,Ilen,包含每行中真实条目的数量。但是,如果一行中的非零条目数量超过了猜测,您仍然需要重新分配和复制。