2D区域的内存布局

Posted

技术标签:

【中文标题】2D区域的内存布局【英文标题】:Memory layout of 2D area 【发布时间】:2018-03-13 22:59:11 【问题描述】:

内存中的二维区域布局如何?特别是如果它是一个交错的区域。鉴于,据我了解,内存从 Max 下降到 0 是连续的,计算机是否一个接一个地分配该区域中的每个区域?如果是这样,如果该区域中的一个区域需要调整大小,是否会向下移动所有其他区域以便为新调整的区域腾出空间?

如果需要具体说明:

C++17/14/11

叮当

linux x86

修订:(感谢 user4581301)

我指的是有一个vector<vector<T>>,其中T 是一些已定义的类型。我不是在谈论模板编程,除非这不会改变任何东西。

【问题讨论】:

我们是在谈论 C++ 对内存的看法吗?操作系统的内存视图还是内存的物理地址?对于内存的布局和寻址方式,上述每一个都有不同的想法。 内存的差异会不会完全不一样? 【参考方案1】:

std::vector 如何实现的具体细节因编译器而异,但很可能std::vector 包含一个size_t 成员,用于存储长度和指向存储的指针。它使用您在模板中指定的任何分配器分配此存储,但默认使用new,它将它们从堆中分配。您可能知道这一点,但通常堆是内存中堆栈下方的 RAM 区域,随着堆栈从顶部向下增长,它从底部向上增长,并且运行时通过跟踪它的哪些块是空闲的来管理它。

std::vector 管理的存储是一个连续的对象数组,因此由 T 的 20 个向量组成的向量将至少包含一个存储值 20 的 size_t,以及一个指向由 20 个结构组成的数组的指针每个都包含一个长度和一个指针。这些指针中的每一个都将指向T 的数组,该数组连续存储在内存中。

如果您改为创建一个矩形二维数组,例如T table[ROWS][COLUMNS]std::array< std::array<T, COLUMNS>, ROWS >,您将获得一个以行优先顺序存储的单个连续 T 元素块,即:所有元素第 0 行的所有元素,然后是第 1 行的所有元素,依此类推。

如果你事先知道矩阵的维数,矩形数组的效率会更高,因为你只需要分配一块内存。这更快,因为您只需要调用一次分配器和析构器,而不是每行一次,还因为它会在一个地方,不会拆分到许多不同的位置,因此单个块更多可能在处理器的缓存中。

【讨论】:

【参考方案2】:

vectors 是动态分配的元素数组周围的瘦包装器。对于vector<vector<T>>,这意味着外部vector 的内部数组包含内部vector 结构,但内部vectors 分别分配和管理自己的内部数组(该结构包含指向托管的指针数组)。

本质上,2D 方面纯粹是在程序逻辑中;任何给定“行”的元素都是连续的,但行之间没有指定的空间关系。

真正的 2D 数组(其中底层内存被分配为单个块)仅在使用 2D 语法 (int foo[10][20];) 和嵌套 std::array 类型或遵循相同基本设计的 POD 类型声明的 C 样式数组中才会发生.

【讨论】:

相关切线:这种空间关系的缺乏会导致缓存行为不佳,并对性能造成惊人的巨大影响。 @user4581301:是的。主要优点是在 OP 提到的调整大小的情况下,因为每个vector 的大小是独立的,并且调整一个vector 的大小只需移动那个vector 的内容,而不是整个二维结构。随机访问速度较慢,但​​调整大小更快,并且每行的大小可以独立。

以上是关于2D区域的内存布局的主要内容,如果未能解决你的问题,请参考以下文章

深入JVM之理解JVM内存区域与对象创建内存布局

编译器如何在内存中布局代码

linux进程内存布局

JVM内存布局

JVM内存布局

[转帖]详解JVM内存布局及GC原理,值得收藏