我的理解是硬件预取永远不会跨越页面边界。我想知道软件预取是否具有相同的限制,即我可以使用软件预取来避免未来的 TLB 未命中。通过四处搜索,这似乎是可能的,但我在文档中找不到任何确定的东西,所以参考会很好。
我对 Nehalem、Sandy Bridge 和 Westmere 特别感兴趣。
根据英特尔的优化参考手册,它取决于处理器。从第 7.4.3 节开始:
在某些情况下,PREFETCH 不会执行数据预取。这些包括:
- PREFETCH 导致 DTLB(数据转换后备缓冲区)未命中。这适用于具有对应于系列 15、型号 0、1 或 2 的 CPUID 签名的 Pentium 4 处理器。PREFETCH 解决 DTLB 未命中并在具有对应于系列 15、型号 3 的 CPUID 签名的 Pentium 4 处理器上获取数据。
- 对导致故障/异常的指定地址的访问。
软件预取可能会也可能不会避免 TLB 未命中,具体取决于处理器。如果它会导致页面错误,它将不会获取数据。
如果要确保避免 TLB 未命中,可以执行虚拟读取来加载数据,而不是预取指令。这可能会导致页面错误交换页面,根据您的用例,这可能是好是坏。
在现代处理器(Nehalem、Sandy Bridge 和 Westmere)中,软件预取确实会触发 TLB 查找。
来自英特尔优化指南:(第 7.3.3 节)
在较旧的微架构中,会丢弃导致数据转换后备缓冲区 (DTLB) 未命中的 PREFETCH。在基于 Nehalem、Westmere、Sandy Bridge 和更新的微架构、Intel Core 2 处理器和 Intel Atom 处理器的处理器中,可以跨页边界获取导致 DTLB 未命中的 PREFETCH。