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】:vector
s 是动态分配的元素数组周围的瘦包装器。对于vector<vector<T>>
,这意味着外部vector
的内部数组包含内部vector
结构,但内部vector
s 分别分配和管理自己的内部数组(该结构包含指向托管的指针数组)。
本质上,2D 方面纯粹是在程序逻辑中;任何给定“行”的元素都是连续的,但行之间没有指定的空间关系。
真正的 2D 数组(其中底层内存被分配为单个块)仅在使用 2D 语法 (int foo[10][20];
) 和嵌套 std::array
类型或遵循相同基本设计的 POD 类型声明的 C 样式数组中才会发生.
【讨论】:
相关切线:这种空间关系的缺乏会导致缓存行为不佳,并对性能造成惊人的巨大影响。 @user4581301:是的。主要优点是在 OP 提到的调整大小的情况下,因为每个vector
的大小是独立的,并且调整一个vector
的大小只需移动那个vector
的内容,而不是整个二维结构。随机访问速度较慢,但调整大小更快,并且每行的大小可以独立。以上是关于2D区域的内存布局的主要内容,如果未能解决你的问题,请参考以下文章