内存对齐与页面对齐

时间:2015-01-14 19:39:34

标签: c# c++ c performance caching

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

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

因此,我的问题是,是否存在某种规则或阈值,指出我们何时应故意错位数据以避免页面对齐问题;何时不能获得标准内存对齐的好处?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

如果性能对您的应用程序至关重要,并且您的应用程序通常在已知数据集(类型和大小)上进行迭代,那么了解和理解MMU,L-caches和缓存行的影响非常重要。不是因为你可以提前避免这些问题,而是因为你可能需要事后识别它们,同时盯着分析结果并试图弄清楚为什么某些东西比以前更长或者“通常应该“。并且 - 如果你很幸运并且数据集足以控制你 - 你可以调整一些东西来解决某种cpu缓存性能问题。

不幸的是,大多数应用程序没有遍历已知数据集并了解其目标硬件类型的奢侈品。这是游戏和多媒体应用程序开发以及操作系统工程中相当独有的东西。对于世界上大多数其他应用程序,改进某个特定大小的特定数据集的缓存配置文件意味着将其减少为另一个。

最后,即使是“将我们的变量与N字节边界对齐”的“经验法则”也受到底层硬件的影响。大多数较新的桌面级x86架构(大多数是在大约2011年之后制造)更喜欢打包数据而不是对齐数据,因为加载跨越高速缓存行边界的单词的成本变得比加载更多总高速缓存行来表示相同数据集更便宜。但在运行ARM的移动设备上?对齐仍然非常重要。

为了进一步教育,您可以搜索更多关键字:缓存着色缓存逐出。但同样,这一切都非常依赖于目标CPU,遗憾的是很少(或没有)概括。