访问用于表示整数格的优化数据结构

计算科学 矩阵 网格 内存管理 拉普拉斯算子
2021-12-09 19:23:59

中的整数格,即集合,让的某个有界子集上定义的函数的离散(图)拉普拉斯,用表示,在点定义为 即我们对 的所有晶格邻居求和减去给定点的函数值乘以(这是,因为维度)。2dZ2={(x,y):x,yZ}u:Z2RZ2uΔ1(x,y)

(1)Δ1u(x,y)=u(x+1,y)+u(x1,y)+u(x,y+1)+u(x,y1)4u(x,y),
(x,y)42dd=2

为了数值计算离散的拉普拉斯,我将晶格(当然是它的一部分)表示为数组,因此的值存储在复制网格鉴于的性质,当我需要在数组的某个索引处计算它时,我需要跳过数组的一行以访问2du2dΔ1(i,j)(i,j). 这显然不是访问数组的有效方式,因为我们强制指针重复跳过大块内存位置。确实,对于过度计算给定函数的拉普拉斯的某些问题(例如,在某些迭代过程中),即使矩阵的大小适中(例如),与具有相同数量的操作但没有数组访问512×512

问题:是否有一种有效的方法(数据结构)来表示网格以优化上述形式的数组访问操作?说,专门针对中的访问模式。2d(1)

我知道数组的空间和时间优化,以及重复访问相同的内存位置,编译器可能会将这些指针提升到注册表中。但是,在我的情况下,访问模式不是很规律。

当然,这个问题相当幼稚,但由于网格是一个无处不在的对象,如果您能分享您对有关它的有效数据结构的见解,我将不胜感激。2d

2个回答

本质上,您是在询问是否可以枚举域内从的东/西/北/南邻居需要访问位置使得索引和这四个索引之间的距离最小。1Nnne,nw,nn,nsn

这个问题相当于对矩阵的行和列进行洗牌,使其带宽变得最小。Cuthill-McKee 等算法用于计算行和列的排列以实现此目的。

但是,可以证明,如果您的域是整数格的平方部分,方向上的节点之间(即,您总共有 lattice sites),则没有将带宽(即)降低到以下值 . 换句话说,您无法避免访问存储在内存中很远的元素。dxyN=(d+1)2max{|nnE|,|nnW|,|nnN|,|nnS|}d

您可以通过将数组存储在 4x4 方形子数组中来加快速度,以便它们中的每一个都适合高速缓存行(64 字节 = 4x4 32 位整数)。这将内存访问次数的概率分布从 [0,0,1](平均访问次数 = 3)(对于 1,2 或 3 次访问)更改为 [1/4,1/2,1/4] (平均访问次数 = 2)。

也许一些空间填充曲线也可以帮助一点https://en.wikipedia.org/wiki/Hilbert_curve