在x86中刷新iCache

时间:2011-10-21 19:22:36

标签: caching x86 intel flush

无论如何我可以在x86架构中刷新iCache吗?与WBINVD一样,它将使数据缓存中的所有缓存行无效并刷新。

1 个答案:

答案 0 :(得分:2)

根据文档, wbinvd刷新所有缓存并使它们无效,而不仅仅是数据缓存和统一缓存。 (如果您启用了分页功能,则无法确定其中是否包含TLB。)


您要测试什么? L1i miss / L2 hit for code-fetch吗?我认为不可能故意刷新 just I-cache而又不刷新所有级别的缓存。

假设在8位32kiB L1i高速缓存中执行别名的8个地址的代码,则可能会为特定行创建冲突未命中。但是缓存替换通常是伪LRU,而不是真正的LRU,因此,您可能需要几次跳过一组超过8条别名行才能确定。


clflush / clflushopt应该为特定的缓存行解决问题。他们需要从所有内核的 all 缓存级别中清除行。

我认为它们也会从(虚拟寻址的)uop缓存中逐出已解码的uop。

  

CLFLUSH指令可以在所有特权级别使用,并且受制于所有权限检查和与字节加载相关的错误(此外,此外,CLFLUSH指令允许在仅执行中刷新线性地址细分)。像加载一样,CLFLUSH指令将页表中的A位置位,但不将D位置。


但是,如果您希望在进行JIT编译后保持这种正确性,只需跳转或调用新编写的指令就足以避免获取过时的指令。

(实际上,在当前的x86实现中,它们监听存储到管道中的任何代码地址,因此即使将相同的物理页面映射到不同的虚拟地址,也永远不会看到过时的指令提取,并且执行另一个Observing stale instruction fetching on x86 with self-modifying code


您只需要担心编译器将“死存储”优化为转换为函数指针的缓冲区。在GNU C / C ++中,在您编写的字节范围上使用__builtin___clear_cache。它可以在x86上编译为零指令(与ARM或其他具有非一致性指令缓存的ISA不同),但是仍然需要不优化指令字节的存储:How does __builtin___clear_cache work?