当前指令旁边的 RIP 相关加载会发生什么情况?缓存命中?
What happens for a RIP-relative load next to the current instruction? Cache hit?
我正在阅读 Agner Fog 关于 x86 汇编的书。我想知道 RIP 相对寻址在这种情况下是如何工作的。具体来说,假设我的 RIP 偏移量是 +1。这表明我要读取的数据就在内存中这条指令的旁边。
这条数据很可能已经被提取到 L1 指令缓存中。假设这个数据不在L1d中,那么在CPU上究竟会发生什么?
我们假设它是相对较新的 Intel 架构,例如 Kaby Lake。
是的,它在 L1i 缓存和 uop 缓存中可能很热。该页面在 L1iTLB 中也很热门。但所有这些都与数据加载无关。
由于指令获取,它在 L2 中可能很热,但它可能从那时起就被驱逐了(L2 是 NINE wrt。L1 缓存)。 所以最好的情况是在 L2 中命中。
L1iTLB 和 L1dTLB 是分开的,因此如果这是从该页面加载的第一个数据,它将在 L1dTLB 中丢失。如果统一的二级 TLB 是受害者缓存,它可能会错过那里,甚至触发页面遍历,尽管在 L1iTLB 中很热,但是 。不过,这是有道理的;同一页面中的代码和数据通常很少见。 (尽管比同一 行 中的代码和数据更少见。)
另请参阅 了解一些详细信息和讨论。但请注意,这是一个错误的说法,编译器 不要 在 x86 上这样做,因为它对性能有帮助(浪费 TLB 覆盖足迹,浪费缓存容量),这与 ARM 不同,后者是常量函数之间的池是正常的,因为 PC 相对寻址的范围非常有限。只有一些混淆器可能会这样做。
Specifically, assume my RIP offset is +1. This suggests the data I want to read is right next to this instruction in memory
rel32
是相对于当前指令的end。所以不,不在右边旁边;那将是一个 1 字节的间隙。
例如像这样:
movzx eax, byte [rip + 1]
ret
; could be a page boundary here
load_target: int3 ; db 0xcc
请注意,如果指令在页面边界的 0 或 1 字节内结束,[RIP+1]
可能与使用该寻址模式的指令位于不同的缓存行甚至页面中。
那个 1 字节甚至可以是一个 ret
,所以这条指令可能已经在执行,而前端还没有(或曾经)从其他行或页面中获取,就像它会否则。我认为您对从包含当前指令的同一行中获取的情况更感兴趣。不妨说 mov eax, [RIP - 4]
从当前指令的机器代码中获取 -4
rel32 本身。
加载不会触发自修改代码管道核弹,只会触发存储,所以没关系。
我正在阅读 Agner Fog 关于 x86 汇编的书。我想知道 RIP 相对寻址在这种情况下是如何工作的。具体来说,假设我的 RIP 偏移量是 +1。这表明我要读取的数据就在内存中这条指令的旁边。
这条数据很可能已经被提取到 L1 指令缓存中。假设这个数据不在L1d中,那么在CPU上究竟会发生什么?
我们假设它是相对较新的 Intel 架构,例如 Kaby Lake。
是的,它在 L1i 缓存和 uop 缓存中可能很热。该页面在 L1iTLB 中也很热门。但所有这些都与数据加载无关。
由于指令获取,它在 L2 中可能很热,但它可能从那时起就被驱逐了(L2 是 NINE wrt。L1 缓存)。 所以最好的情况是在 L2 中命中。
L1iTLB 和 L1dTLB 是分开的,因此如果这是从该页面加载的第一个数据,它将在 L1dTLB 中丢失。如果统一的二级 TLB 是受害者缓存,它可能会错过那里,甚至触发页面遍历,尽管在 L1iTLB 中很热,但是
另请参阅
Specifically, assume my RIP offset is +1. This suggests the data I want to read is right next to this instruction in memory
rel32
是相对于当前指令的end。所以不,不在右边旁边;那将是一个 1 字节的间隙。
例如像这样:
movzx eax, byte [rip + 1]
ret
; could be a page boundary here
load_target: int3 ; db 0xcc
请注意,如果指令在页面边界的 0 或 1 字节内结束,[RIP+1]
可能与使用该寻址模式的指令位于不同的缓存行甚至页面中。
那个 1 字节甚至可以是一个 ret
,所以这条指令可能已经在执行,而前端还没有(或曾经)从其他行或页面中获取,就像它会否则。我认为您对从包含当前指令的同一行中获取的情况更感兴趣。不妨说 mov eax, [RIP - 4]
从当前指令的机器代码中获取 -4
rel32 本身。
加载不会触发自修改代码管道核弹,只会触发存储,所以没关系。