我使用有限元理论中的一个例子,但是任何维护大型数据结构并连续扩展它的人都会发现类似的东西。
假设我有一个点和三角形的非结构化网格,其中点由坐标给出(比如和) 并且每个三角形都由三个点索引组成(比如,和)。
正如 FEM 中常见的那样,网格将被逐次细化。如果我们求助于全局规则细化,三角形的数量将成倍增长随着细化的每次迭代。根据执行方式的不同,内存布局会有所不同。
假设网格占用了 1 到 300 个存储单元,除此之外的任何内容都是免费的。
示例 1:
我们为新网格分配空间,单元格 301 到 1501,用细化网格的数据填充它,然后忘记旧网格。下一个细化网格将放置在单元格 1501 到 6300 中,下一个在 6301 到 21500 中,依此类推。当前网格的位置将在内存中“向右”移动,而不会使用巨大的补丁。我们可能会过早地耗尽内存。
人们可能会在上面的示例中观察到,这只会阻碍我们进行一次细化,因为即使没有碎片,我们也会在一次细化后耗尽总内存。由于也考虑了顶点数组,问题可能会变得更加严重。
如何避免这种情况?
示例 2:
将三角形数组重新分配到单元格 1..1200。在单元格 1201 到 2400 中创建新网格。将该工作副本的内容复制到单元格 1..1200,然后忘记工作副本。类似地重复。
好的,我们仍然过早地耗尽了内存,因为我们需要一个工作副本。这个怎么样:
示例 3:
将三角形数组重新分配到单元格 1..1500。将旧网格复制到 1201 .. 1500。在单元格 1..1200 中创建新网格。然后忘记旧网格的副本。
这里的情况是人为的,因为人们不会在这些尺度上使用全局网格细化。如果增长要小得多,则可以重新调整内存以避免碎片。然而,
问题:
内存碎片在实际科学计算/高性能计算中是否变得至关重要?
如果有的话,你如何避免它?也许我的机器模型甚至是错误的,并且操作系统通过一些重魔法确实会默认重新调整内存,或者管理堆上的碎片块。
更具体地说,它如何影响网格管理?