我们经常听说将变量对齐到内存中的 N 字节边界可以提高性能(通过防止 CPU 必须将两个单独的“字”加载到缓存中才能读取我们的变量)。
另一方面,我们也(不太经常)听到将大块内存(数组/缓冲区)对齐到一个漂亮的、圆形的二次幂地址可能是不好的,因为将内存地址分配给的哈希函数缓存地址不再统一(这称为页面对齐)。
因此,我的问题是,关于我们何时应该故意错位数据以避免页面对齐问题,是否存在某种规则或阈值点?什么时候不这样做,以获得标准内存对齐的好处?
最佳答案
如果性能对您的应用程序特别重要,并且您的应用程序通常迭代已知数据集(类型和大小),那么了解和理解 MMU、L 缓存和缓存行的影响非常重要。并不是因为您真的可以提前避免这些问题,而是因为您可能需要在事后确定它们,同时盯着分析结果并试图弄清楚为什么某些事情花费的时间比以前长,或者“通常应该”而且——如果你幸运并且数据集在你的控制范围内——你可以调整一些东西来解决某种 cpu 缓存性能问题。
不幸的是,大多数应用程序都无法迭代已知数据集,也无法知道它们的目标硬件类型。这是游戏和多媒体应用程序开发以及操作系统工程所独有的东西。对于世界上大多数其他应用程序,改进某个特定大小的特定数据集的缓存配置文件意味着减少另一个数据集的缓存配置文件。
最后,即使是关于“将我们的变量对齐到 N 字节边界”的“经验法则”也受制于底层硬件。大多数较新的桌面级 x86 架构(大多数大约在 2011 年之后制作)更喜欢打包数据而不是对齐数据,因为加载跨缓存行边界打包的单词的成本已经变得比必须加载更多的总缓存行来表示相同的数据集更便宜。但是在运行 ARM 的移动设备上呢?对齐仍然非常关键。
您可以搜索更多关键字以进行进一步教育:缓存着色 和缓存逐出。但同样,这都非常依赖于 objective-c PU,不幸的是,几乎没有(或没有)概括。
关于c# - 内存对齐与页面对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27951041/