无论如何我可以在x86架构中刷新iCache吗?像WBINVD一样,它将使数据缓存中的所有缓存行无效并刷新。
根据文档,wbinvd
刷新并使所有缓存无效,而不仅仅是数据和统一缓存。 (如果你在启用分页的情况下运行它,我不确定它是否包含TLB。)
你想测试什么? L1i miss / L2 hit for code-fetch?我不认为有可能只是故意刷新I-cache而不会刷新所有级别的缓存。
假设8路32kiB L1i缓存,您可以通过在8个地址处执行代码来为特定行创建冲突未命中。但缓存替换通常是伪LRU,而不是真正的LRU,因此您可能需要多次跳过一组超过8个别名行以确保。
clflush
/ clflushopt
应该为特定的缓存行做技巧。他们需要从所有核心的所有级别的缓存中刷新线路。
我假设它们也会从(虚拟寻址的)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?