内存对齐与页面对齐
Memory Alignment vs Page Alignment
我们经常听到将变量与内存中的N字节边界对齐可以提高性能(通过防止CPU必须将两个单独的"字"加载到缓存中来读取我们的变量)。
另一方面,我们也听到(不太常见)将大块内存(数组/缓冲区)对齐到一个漂亮的圆形二次幂地址可能是不好的,因为将内存地址分配给缓存地址的哈希函数不再统一(这称为页面对齐)。
因此,我的问题是,是否有某种规则或阈值点来说明我们何时应该故意错位数据以避免页面对齐的问题;何时不这样做,以获得标准内存对齐的好处?
如果性能对应用程序的特殊性至关重要,并且应用程序通常循环访问已知数据集(类型和大小),则了解和理解 MMU、L 缓存和缓存行的影响非常重要。 不是因为您可以提前真正避免这些问题,而是因为您可能需要在事后识别它们,同时盯着分析结果并试图弄清楚为什么某些事情比以前或"通常应该"花费的时间更长。 而且 - 如果你很幸运并且数据集在你的控制范围内足够 - 你可以调整一些东西来解决某种CPU缓存性能问题。
不幸的是,大多数应用程序无法迭代已知数据集并了解其目标硬件类型。 这是游戏和多媒体应用程序开发以及操作系统工程所独有的。 对于世界上大多数其他应用程序,改进某个特定大小的特定数据集的缓存配置文件意味着减少另一个数据集的缓存配置文件。
最后,即使是关于"将变量与 N 字节边界对齐"的"经验法则"也受制于底层硬件。 大多数较新的桌面级 x86 体系结构(大多数是在大约 2011 年之后制作的)更喜欢打包数据而不是对齐数据,因为加载跨缓存行边界打包的单词的成本已经变得比必须加载更多总缓存行来表示同一数据集的成本要低。 但是在运行 ARM 的移动设备上? 对齐仍然非常关键。
更多关键字供您搜索,用于进一步教育:缓存着色和缓存逐出。 但同样,这一切都非常依赖于目标 CPU,不幸的是,很少(或没有)概括。
我认为你不能得到一个一般的规则。这取决于您使用的处理器,即底层系统的 MMU 和缓存实现。这将因系统而异。因此,如果您想要最佳性能,则需要了解当前系统的所有低级细节。一般来说,我希望将大内存块对齐到二次方边界的好处是有限的。
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在 64 位边界上对齐C++结构数组?
- 使用 g++7 构建的代码在访问未对齐的内存时崩溃
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 是否值得对齐变量?
- 初始化派生结构的基部分/意外打包派生结构字段以对齐基结构的间隙
- 对齐和对齐的实际用例C++关键字
- 如何减少代码的运行时间以对齐文本?
- 指向包含对齐 C 结构C++类的 C 指针的对齐问题
- Linux C++ 中的页面对齐内存分配
- C++ 类层次结构中的"对齐"是什么意思?
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 具有调整对齐方式的类型定义
- 内存对齐与页面对齐