【问题标题】:Is there a penalty for accesses to virtual addresses which are mapped to the same physical address?访问映射到同一物理地址的虚拟地址是否会受到惩罚?
【发布时间】:2018-06-06 01:19:19
【问题描述】:

鉴于进程操作的虚拟地址和表示内存中实际位置的物理地址之间的分离,您可以玩一些有趣的技巧:例如创建一个@ 987654321@.

我想知道这种映射技巧是否会在这种情况下对数据读取或写入访问造成惩罚:

  • 对物理页面的访问主要是通过相同的虚拟映射,但偶尔会通过其他映射。
  • 对物理页面的访问或多或少平均分布在映射到同一物理地址的虚拟地址之间。

我对过去十年左右发布的 x86 芯片特别感兴趣,同时也对当代 ARM 和 POWER 芯片感兴趣。

【问题讨论】:

  • 您只关心数据访问,而不关心代码获取,对吧?我认为英特尔的优化手册提到对相同的物理页面有多个映射,但我忘记了我读过的内容。我认为只有当其中一个映射是回写但另一个不是(例如 USWC)时才会受到惩罚。哦,存储/加载重叠检测可能会推测性地假设页面只映射一次,因此值得检查。
  • @PeterCordes 是的,我在考虑数据访问,虽然我想在代码方面也有很酷的技巧:)
  • IIRC,uop 缓存是虚拟寻址的,因此代码的多个映射可能效率较低。 JITing 到一个页面然后通过别名执行它可能也不是很好,我忘记了。

标签: performance memory-management x86 cpu-architecture mmap


【解决方案1】:

如果您正在寻找可能的惩罚,我将从加载存储转发逻辑开始。如果你有一个存储到虚拟地址 A,然后从 B 加载,并且两个地址都映射到同一个物理地址,你会把你的 CPU 搞得一团糟。

主要问题是必须尽早解决这些冲突,以加快加载速度(大多数微架构通常都针对这一点进行了优化),因此如果您知道某些设计可能会匹配虚拟地址(或其中的一部分)及时(如果没有,您可以使用记忆消歧,但那是另一回事)。 请记住,L1 集映射通常查看 12 个较低的 addr 位,这允许您的 L1 查找和 TLB 查找并行执行 - 如果您还必须等待与任何早期存储的完全匹配,这将是不可能的在系统中。幸运的是,由于最小的 4k 粒度,如果您为虚拟页面添加别名,您仍然可以获得相同的低 12 位,所以这种匹配仍然有效。

但是,为了在功能上万无一失,稍后必须有一个完整的物理匹配(一旦您获得了负载和所有旧商店的完整翻译),因此设计可能会在那时决定无论是不想基于部分匹配转发数据(并且冒着必须刷新所有内容的风险),还是等待完整匹配。无论哪种方式都可能会导致一些延迟,但我认为除非您打破早期的部分检查,否则别名不会对此产生影响。

【讨论】:

  • 正如 Brendan 指出的那样,即使没有虚拟内存技巧,英特尔 CPU 也会将模 4k 别名视为依赖项。即如果地址是 4k 的倍数,即使在同一个 2M 大页面内,内存消歧会失败。我和你一样担心商店转发检测,但事实证明我们总是付出代价;似乎虚拟地址的高位(高于页面偏移量)从未用于存储转发检查,甚至不是推测性的。
【解决方案2】:

对于 80x86(我不知道其他架构):

a) 普通指令/数据/统一缓存是物理索引的(因此不受分页技巧的影响)

b) TLB 被虚拟索引。这意味着(取决于很多事情),对于您的循环缓冲区技巧,您可能会比没有循环缓冲区技巧时看到更多的 TLB 未命中。可能重要的事情包括区域的大小和使用的 TLB 条目类型的数量(4 KiB,2 MiB/1 GiB);如果 CPU 预取 TLB 条目(最近的 CPU 会这样做),并且有足够的时间花在其他工作上以确保预取的 TLB 在需要之前到达;如果 CPU 缓存更高级别的分页结构(例如页目录)以避免在 TLB 未命中时获取每个级别(例如,单独的页表条目,因为页目录已被缓存;或 PML4 条目然后是 PDPT 条目然后是 PD 条目然后是页表条目) .

c) 任何 uop 缓存(例如,作为循环流检测器的一部分,或旧的 Pentium 4“跟踪缓存”)都被虚拟索引或根本没有索引(例如,CPU 只记住“从循环开始的 uops”)。除非您有多个代码副本,否则这无关紧要;如果你确实有多个代码副本,它就会变得复杂(例如,如果重复导致 uop 的数量超过 uop 缓存的大小)。

d) 分支预测是虚拟索引的。这意味着如果您有相同代码的多个副本,它会再次变得复杂(例如,对于静态预测不正确的分支,它会增加“训练时间”;并且重复会导致分支数超过分支预测数槽并导致更差的分支预测)。

e) 返回缓冲区是虚拟索引的,但我想不出这有什么关系(复制代码不会增加调用图的深度)。

f) 用于存储缓冲区(用于存储转发);如果商店在不同的虚拟页面上,那么他们必须假设商店可能有别名,无论它是否存在;因此应该没关系。

g) 用于写入合并缓冲区;老实说,我不确定它们是虚拟索引还是物理索引。如果它可能很重要,您可能会在它真正重要之前用完“写入组合插槽”。

【讨论】:

  • 我几乎可以肯定写组合缓冲区(行填充缓冲区)仅使用物理地址。相同的缓冲区用于来自其他缓存的进出 L1D 的行,这些缓存当然是物理寻址的。此外,在执行每个存储而不是在 LFB 中合并之后检查 TLB 更有意义。将 NT 存储与常规存储混合并加载到同一地址时必须保持正确性,并且跟踪它们的结构使用物理地址。 (如果它在缓存中已经很热,则 NT 商店保证驱逐一行)
  • Sandybridge 系列中的“uop 缓存”(我认为,DSB = 解码流缓冲区)与循环缓冲区是分开的。它们都缓存了微指令,但 Nehalem 只有 LSD,没有其他微指令缓存。因此,常规的 uop 缓存并不是严格意义上的 LSD 的“一部分”。 LSD uop 缓存,但不是 uop 缓存。但无论如何,是的,在英特尔 CPU 中,它们实际上都得到了解决。我认为我们没有关于 Ryzen uop 缓存的详细信息。物理寻址的 uop 缓存是一种合理的设计。指令中的相对位移很容易保持相对。不过,它确实节省了 ITLB 查找的电量。
  • @PeterCordes 您可以在 Ryzen 上的David Kanter's article 中找到有关 AMD uop 缓存(以及更多)的详细信息。它详细解释了 uop 缓存:特别是,它是物理寻址的。 LFB 很可能是物理索引的:毕竟,它们仅在 L1 未命中后才分配,此时翻译很可能完成!
  • @BeeOnRope:不是“唯一”。 LFB 也由 NT 存储直接分配,这是 Brandon 在称它们为“写入组合缓冲区”时所考虑的。但是,是的,除了 NT 商店之外,他们的其他商店几乎可以肯定他们使用物理地址。
  • @PeterCordes NT 商店也必须探测 L1,因为他们需要将他们拥有的任何数据与 L1 中同一行中的数据(如果存在)结合起来。所以也许我应该说“它们只在 L1 探测之后分配”。 NT 商店就像一个商店,它始终遵循商店的错误处理路径,即使它命中也是如此。靠近 L1,它可能使用与 L1 驱逐相同的机制和硬件。
猜你喜欢
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多