X86 CPUID会序列化推测性数据缓存吗?

X86 CPUID会序列化推测性数据缓存吗?,x86,cpu-cache,microbenchmark,cpuid,micro-architecture,X86,Cpu Cache,Microbenchmark,Cpuid,Micro Architecture,我在《英特尔第二卷》的多条指令项中找到了关于推测性数据缓存过程的描述 例如: 处理器可以自由地推测性地从区域获取和缓存数据 使用WB、WC和WT内存类型的系统内存。这 投机性抓取可以在任何时候发生,并且不受限制 指令执行。因此,它不是针对 执行LFENCE指令;数据可以被带到数据库中 在执行某个命令之前、期间或之后进行推测性缓存 LFENCE指令 此外,我从在线资源中发现,推测性缓存也会将数据从较远的缓存移动到较近的缓存 我想知道最强的序列化指令CPUID是否会阻止投机性缓存越过屏障 我已经搜索

我在《英特尔第二卷》的多条指令项中找到了关于推测性数据缓存过程的描述

例如:

处理器可以自由地推测性地从区域获取和缓存数据 使用WB、WC和WT内存类型的系统内存。这 投机性抓取可以在任何时候发生,并且不受限制 指令执行。因此,它不是针对 执行LFENCE指令;数据可以被带到数据库中 在执行某个命令之前、期间或之后进行推测性缓存 LFENCE指令

此外,我从在线资源中发现,推测性缓存也会将数据从较远的缓存移动到较近的缓存

我想知道最强的序列化指令
CPUID
是否会阻止投机性缓存越过屏障


我已经搜索了英特尔第二卷中的
CPUID
条目和英特尔第三卷中的“序列化指令”部分。但它并没有显示推测性数据缓存。

LFENCE已经足够强大(至少在实践中)可以阻止CPU在它之后实际查看加载指令,但CPU可以出于其他原因随意推测加载

要停止这项操作,需要通过某种方式的预先检查,以找出要禁用硬件预取的地址。那根本不实际。CPUID或其他序列化指令在停止加载预取方面并不比LFENCE强

始终允许CPU推测性地从WB和WT区域/页面中的内存中提取数据。英特尔的优化手册在一些CPU型号中记录了一些关于硬件预取器的内容,因此在实践中,您可以避免在CPUID之前执行可能触发此类预取的操作

(WC是弱有序的不可缓存+写入组合,但也允许在纸面上进行推测性提取。在现实生活中,这可能只发生在分支预测失误的阴影下,而不是HW预取。它通常不像WB和WT那样可缓存。)


如果您正在对一个真正的CPU进行微基准标记,某些类型的微基准标记的诀窍是找到一种不会触发硬件预取的访问模式,或者禁用硬件预取器


从理论上讲,也许你可以拥有一个x86 CPU,它在指令流中查找加载/存储指令,并推测性地预取这些指令,而不是实际执行它们(英特尔对LFENCE的定义会阻止它们)。我也不认为有什么能阻止它在CPUID上这样做

可能没有人会设计这样的CPU,因为

  • 它不值这些晶体管/功率。一旦常规的无序执行能够达到,就开始预取已经足够好了。除绝对/RIP相对地址或直接跳转外,您需要从OoO内核中注册值以获得有用的预取地址
  • 看过去的LFENCE/CPUID是反常的;它们非常罕见,在幽灵时代,击败过去的投机性负载“执行”是关键的一部分

  • 仔细考虑之后,我认为硬件预取器是一种独立的单元,与指令流并行运行。指令流给出提示,然后预取器独立地将数据提取到缓存。我说得对吗?在我的心智模型中,
    lfence
    更像是一个“指令围栏”,而不是一个“负载围栏”,因此我将其与
    cpuid
    进行比较,发现
    cpuid
    中引用的段落的缺失很奇怪。也许这一段的目的是为了解决这条指令的“加载界限”部分,因为加载到缓存是一种“加载”。因此,
    cpuid
    @user10865622:yup中不包含此段落,并且共享缓存(在多个内核之间共享)也可以具有预取器。我忘了Intel或AMD当前的CPU是否有L3预取。在Intel上,大多数PF逻辑在每核L2中是专用的,有些在L1d和L1i中。至于为什么CPUID没有类似的语言,是的,可能是因为指令的名称暗示内存顺序。(但是是的,它对内存排序几乎毫无用处,只对指令排序。
    lfence
    的唯一内存顺序用例是我认为从WC内存排序NT加载:作为加载和加载存储屏障,但不是存储加载。)对,所有数据预取器只从WB位置(甚至不是WT)预取。请参阅优化手册的2.4.5.4:“加载来自写回内存类型。”此外,预取器不会跨越4KB页面边界,并且内存类型为每页。