内存对齐与页面对齐

Memory Alignment vs Page Alignment

我们经常听说将变量对齐到内存中的 N 字节边界可以提高性能(通过防止 CPU 必须将两个单独的 'words' 加载到缓存中以读取我们的变量)。

另一方面,我们也(不太经常)听到将大块内存 (array/buffer) 对齐到一个漂亮的圆形二次幂地址可能很糟糕,因为散列函数分配内存地址到缓存地址不再统一(这称为页面对齐)。

因此,我的问题是,关于何时我们应该故意错位数据以避免页面对齐问题,是否存在某种规则或阈值点?什么时候不这样做,以获得标准内存对齐的好处?

我认为您无法为此找到一般规则。这取决于您使用的处理器,即底层系统的 MMU 和缓存实现。这将因系统而异。因此,如果您想要获得最佳性能,则需要了解当前系统的所有底层细节。一般来说,我希望将大内存块对齐到二次方边界的好处是有限的。

如果性能对您的应用程序特别重要,并且您的应用程序通常迭代已知数据集(类型和大小),那么了解和理解 MMU、L 缓存和缓存行的影响很重要.并不是因为您真的可以提前避免这些问题,而是因为您可能需要在事后确定它们,同时盯着分析结果并试图弄清楚为什么某些事情比以前花费的时间更长或 "normally should." 并且——如果你很幸运并且数据集在你的控制范围之内——那么你可以调整一些东西来解决某种 cpu 缓存性能问题。

不幸的是,大多数应用程序都没有机会遍历已知数据集,也不知道它们的目标硬件类型。这是游戏和多媒体应用程序开发以及操作系统工程所独有的东西。对于世界上大多数其他应用程序,改进某个特定大小的特定数据集的缓存配置文件意味着减少另一个数据集的缓存配置文件。

最后,甚至关于 "aligning our variables to an N-byte boundary" 的 'rule of thumb' 也受制于底层硬件。大多数较新的桌面级 x86 架构(大多数大约在 2011 年之后制作)更喜欢打包数据而不是对齐数据,因为加载跨缓存行边界打包的单词的成本已经变得比必须加载更多的总缓存行来表示相同的数据集更便宜。但是在移动设备上 运行 ARM?对齐仍然非常关键。

更多关键字供您搜索,以进行进一步教育:缓存着色缓存逐出。但同样,这完全取决于目标 CPU,不幸的是,几乎没有(或没有)概括。