预取指令是否需要在退出之前返回结果?

2024-02-27

在最新的 Intel 和 AMD CPU 上,已执行但请求的行尚未到达指定缓存级别的预取指令是否仍会退出?

也就是说,预取的退休是“阻塞”的,因为它看起来对于加载来说是“阻塞”的,还是非阻塞的?


关于英特尔处理器,没有。 Intel优化手册第7.3.3节提到了这一点:

PREFETCH 可以提供比预加载更好的性能,因为:

  • 没有目标寄存器,它只更新缓存行。
  • 如果这会导致错误,则不会完成自己的执行。
  • 不会停止正常指令的报废。
  • 不影响程序的功能行为。
  • 没有缓存行分割访问。
  • 除非使用 LOCK 前缀,否则不会导致异常。 LOCK 前缀不是与 PREFETCH 一起使用的有效前缀。
  • 如果这会导致错误,则不会完成自己的执行。

PREFETCH 相对于预加载指令的优点是特定于处理器的。这在未来可能会改变。

另外第 3.7.1 节说:

软件预取操作的工作方式与从内存加载相同 操作,但以下情况除外:

  • 软件预取指令在虚拟地址到物理地址转换完成后退出。
  • 如果需要预取数据时出现异常(例如缺页错误),则软件预取指令将退出而不需要 预取数据。

我已经在 Haswell 和 Broadwell 上通过实验验证了这两点。

全部未命中 TLB:所有预取指令均未命中所有 MMU 和数据缓存,但页面位于主内存中(没有次要或主要页面错误)。

全部命中TLB:所有预取指令命中L1 TLB和数据缓存。

不同页面出现故障:所有预取指令都会错过所有 MMU 和数据缓存,并且页面描述符会导致页面故障。每个预取指令访问不同的虚拟页。

同一页故障:所有预取指令都会错过所有 MMU 和数据缓存,并且页描述符会导致页故障。每个预取指令访问相同的虚拟页。

对于 Broadwell 图,两者的结果PREFETCH0 and PREFETCHW显示。PREFETCHWHaswell 不支持。 Haswell 和 Broadwell 的频率分别固定为 3.4GHz 和 1.7GHz,我在两者上都使用了 intel_pstate 功率缩放驱动程序。所有硬件预取器均已打开。请注意,延迟PREFETCHW页面错误与目标页面是否可写无关。只读页导致的故障与任何其他原因导致的故障具有相同的影响。另外,我的实验仅考虑没有核心拥有缓存行副本的情况。

由于 1c 依赖链,预计会出现 1 个周期的吞吐量:

loop:
prefetcht0 (%rax)
add    $0x1000,%rax 
cmp    %rbx,%rax
jne    loop

在 Broadwell 上,“故障相同页面”情况似乎比“故障不同页面”情况稍微慢一些。这与 Haswell 形成鲜明对比。我不知道为什么。这可能取决于包含无效条目的分页结构的级别,基本上页遍历器在该级别上检测到页面错误。这取决于操作系统。

我认为预取指令不能在 TLB 未命中时立即退出的原因是因为加载单元没有像存储单元那样的退出后逻辑。这里的想法是,由于很可能会在预取之后对页面进行需求访问(这可能是预取存在的原因),因此无论是在需求访问还是在预取上,由于 TLB 未命中都会出现停顿。也许在预取上停止会更好,特别是当预取后紧随其后的指令不访问同一页面时。

此外,我已经通过实验验证了预取指令可以在预取操作完成之前退出通过放置一个LFENCE在预取指令之后,观察到与使用加载而不是预取相比,每个预取指令的时间仅略有增加(栅栏的成本)。

Software prefetching instructions on Xeon Phi processors are executed the same way as on Haswell/Broadwell 1, but read also the section on Itanium below.

第 7.3.3 节还指出:

在某些情况下,PREFETCH 不会执行数据预取。 这些包括:

  • 在较旧的微体系结构中,导致数据转换后备缓冲区 (DTLB) 未命中的 PREFETCH 将被丢弃。在基于处理器 Nehalem、Westmere、Sandy Bridge 和更新的微架构、Intel Core 2 处理器和 Intel Atom 处理器、PREFETCH 导致 DTLB miss 可以跨页边界获取。
  • 对指定地址的访问导致错误/异常。
  • PREFETCH 的目标是不可缓存的内存区域(例如,USWC 和 UC)。
  • 如果内存子系统耗尽了一级缓存和二级缓存之间的请求缓冲区。
  • 使用 LOCK 前缀。这会导致无效操作码异常。

第二点已经在Haswell、Broadwell、Skylake上得到了实验验证。我的代码无法检测第四点,即当 LFB 耗尽时可以删除预取请求。这AMD 结果 https://travis-ci.org/travisdowns/pf-test/jobs/432012468似乎表明 AMD 也放弃了预取请求。但AMD上的每次访问时间仍然比Intel上的少很多。我认为当 TLB 填充缓冲区已满时,AMD 会丢弃预取请求,而当 L1D 填充缓冲区已满时,Intel 会丢弃预取请求。我的代码从未使 L1D 填充缓冲区填满,这解释了 AMD 与 Intel 的结果。

第一点是说,在 Core2 和 Atom 微架构及更高版本上,软件预取不会因 TLB 未命中而被丢弃。根据旧版本的优化手册,型号为 3 或更大的 Pentium 4 处理器也不会在 TLB 未命中时放弃软件预取。 Intel Core 微架构和(某些)Pentium M 处理器也可能出现这种情况(我无法找到有关这些处理器的 Intel 来源)。型号小于 3 的 Pentium III 处理器和 Pentium 4 处理器在 TLB 未命中时肯定会放弃软件预取。 Pentium III 之前的处理器不支持软件预取指令。


预取微指令被分派到端口 2 或 3 并分配到加载缓冲区中。预取微指令到同一缓存行不会合并。也就是说,每个微指令都会获得自己的加载缓冲区。我认为(但我没有通过实验验证)ROB 条目是为预取微指令分配的。只是 ROB 永远不会在预取微指令上停止,只要它们已被分派到加载端口。

与常规加载不同,预取请求本身(发送到 L1d 或高速缓存的外部级别)不需要在 ROB 中标记为完成并准备退出之前等待预取 uop。


There is an interesting 2011 patent https://patents.google.com/patent/US9442861B2/en that discusses an enhancement to software prefetching on Itanium2 processors. It mentions that previous Itanium processors had to stall when a software prefetch missed the TLB because they were designed to not drop any software prefetch requests and later instructions could not proceed past it because they were in-order processors. The patent proposed a design that allows software prefetching requests to execute out-of-order with respect to later instructions without dropping them. This is done by adding a data prefetch queue (DPQ) which is used to queue up software prefetch requests that miss the TLB. A prefetch in the DPQ is then re-issued after the hardware page table walk completes. In addition, multiple hardware page table walkers are added to potentially allow later demand accesses to execute even if they miss the TLB. However, if the DPQ fills up with prefetch instructions, the pipeline stalls on the next prefetch instruction. Also according to the patent, software prefetch requests are not dropped even on page faults. This is in contrast to big cores and Xeon Phi. The patent also discusses the hardware prefetchers implemented in Itanium.

在乱序大核心微架构中,加载缓冲器自然扮演着 DPQ 的角色。我不知道Xeon Phi是否有这样的结构。


AMD 优化手册第 5.6 节说道:

预取指令可能会受到错误依赖的影响 商店。如果存在与请求匹配的地址的存储,则 请求(预取指令)可能会被阻止,直到存储完成 写入缓存。因此,代码应该预取数据 与任何周围存储的数据至少相距 64 个字节 地址。

我很好奇,想在 Intel 处理器(Haswell 上)上测试这一点,方法是放置两条预取指令和一条存储指令(后跟一个虚拟指令)add rax, rax),并且我观察到以下情况:

  • UOPS_RETIRED.STALL_CYCLES明显大于核心周期数,这是没有意义的。
  • 发送到端口 2 和 3 的 uop 总数比预期高出约 16%。这表明正在重放预取微指令。
  • RESOURCE_STALLS.ANY报道称基本没有摊位。这与有两个预取指令后跟两个虚拟 ALU 指令的情况形成对比(管道在加载缓冲区上停顿)。

然而,只有当存储与预取指令相同的 4K 页时,我才观察到这些影响。如果存储到不同的页面,则代码的工作方式与具有两个虚拟 ALU 的代码类似。因此,存储似乎与英特尔处理器上的预取指令进行交互。


(1) 但它们与硬件预取器的交互方式不同。然而,这是退休后的影响。

(2) Itanium 是 IA-64 处理器系列,因此与问题并不完全相关。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

预取指令是否需要在退出之前返回结果? 的相关文章

  • 要做或不做:将图像存储在数据库中[重复]

    这个问题在这里已经有答案了 在 Web 应用程序的上下文中 我的前老板总是说在数据库中放置对图像的引用 而不是图像本身 我倾向于同意在数据库中存储 url 与图像本身是一个好主意 但在我现在工作的地方 我们在数据库中存储大量图像 我能想到的
  • CISC 机器 - 它们不只是将复杂指令转换为 RISC 吗?

    也许我在架构上存在误解 但如果机器有 比如说 乘法指令 该指令是否未转换为更小的指令 或者过于复杂以至于最终与等效的 RISC 指令具有相同的速度 乘法是一个不好的例子 它在两种体系结构中都是一条指令 将上面的 乘法 替换为 CISC 中更
  • 为什么乘法比除法便宜?

    我最近编写了一个 Vector 3 类 并将我的 normalize 函数提交给朋友审阅 他说这很好 但我应该尽可能乘以倒数 因为在 CPU 时间上 乘法比除法便宜 我的问题很简单 这是为什么 从硬件可以更轻松地实现的基本运算的角度来考虑
  • 节省页面加载时间的提示[重复]

    这个问题在这里已经有答案了 我的问题 削减那些不必要的 kb 并使页面加载速度更快的最佳方法是什么 全部是什么优化实践 编码实践 在js php中 如果执行可以使您的页面更轻 为什么我问这个 我读了这篇关于 jquery js 与 jque
  • 在生产代码/服务器上运行测试

    我在单元测试 自动化测试方面相对缺乏经验 所以如果这个问题没有任何意义 请原谅 我当前正在处理的代码库耦合如此紧密 以至于我需要重构大部分代码才能对其运行单元测试 所以我阅读了一些帖子并发现了 Selenium 我认为它确实是一个很酷的程序
  • kdb+ 32bit 的性能表现如何

    Kx 宣布 http kx com press releases 140402 php their 免费 kdb http www kxcommunity com 32位 时间序列数据库 我们通常可以期望该数据库的每秒读 写性能如何 我确实
  • 在python中将数据库表写入文件的最快方法

    我正在尝试从数据库中提取大量数据并将其写入 csv 文件 我正在尝试找出最快的方法来做到这一点 我发现在 fetchall 的结果上运行 writerows 比下面的代码慢 40 with open filename a as f writ
  • 如何有效地扫描每次迭代交替的 2 位掩码

    给定 2 个位掩码 应交替访问 0 1 0 1 我尝试获得运行时高效的解决方案 但找不到比以下示例更好的方法 uint32 t mask 2 uint8 t mask index 0 uint32 t f tzcnt u32 mask ma
  • 基于范围的 for 循环对性能有益吗?

    阅读 Stack Overflow 上有关 C 迭代器和性能 的各种问题后 我开始想知道是否for auto elem container 被编译器 扩展 成最好的版本 就像auto 编译器立即将其推断为正确的类型 因此永远不会更慢 有时甚
  • 如何在 AppleScript 的处理程序中有效地构建列表?

    AppleScript 文档建议使用以下代码来有效构建列表 set bigList to set bigListRef to a reference to bigList set numItems to 100000 set t to ti
  • badoo.com 用户搜索 - 如何做到这一点?

    Badoo com 拥有 56 000 000 个用户个人资料 个人资料可以按性别 年龄 发色 生肖 学历等进行搜索 再加上距家乡的距离 在线状态和注册日期 到目前为止 这似乎是可行的 即使它是对巨大表 56m 成员 的相当多的查询 它也可
  • 为什么Python的“sorted()”比“copy,then.sort()”慢

    这是我运行的代码 import timeit print timeit Timer a sorted x x 2 bla 4 boo 3 4 1 2 0 1 4 3 2 1 0 0 timeit number 1000 print time
  • 使用应用程序上下文滑动图像加载

    我在我的 Android 应用程序中使用 glide 进行图像加载 为了避免任何崩溃 我正在使用应用程序上下文加载图像 这对应用程序和内存的性能有何影响 这对应用程序和内存的性能有何影响 Glide提供了这么多 with 方法是有原因的 它
  • 是否有适用于双打 (__m128d) 的 Move (_mm_move_ss) 和 Set (_mm_set_ss) 内在函数?

    多年来 我有几次看到 in 中的内在函数float参数被转换为 m128使用以下代码 m128 b mm move ss m mm set ss a 例如 void MyFunction float y m128 a mm move ss
  • 快速 HTML 表格排序?

    是的 我知道有一个lot有很多 JS jQuery 程序可以做到这一点 我目前正在使用http www kryogenix org code browser sorttable sorttable js http www kryogenix
  • 在 Chrome 18 中检测 SwiftShader WebGL 渲染器

    我有一个 2D HTML5 游戏引擎 www scirra com http www scirra com 并且确实想检测 WebGL 是否将使用 Chrome 18 的 Swiftshader 软件渲染器进行渲染 如果是这样我们会much
  • OpenMP 共享与第一私有性能比较

    我有一个 pragma omp parallel for在类方法内循环 每个线程只读访问很少的方法局部变量 很少调用私有数据和方法的参数 所有这些都在一个声明中声明shared条款 我的问题 性能方面不应该有任何区别声明这些 变量share
  • php 日期函数和 Carbon 哪个更快?

    Carbon 是 DateTime 的简单 PHP API 扩展 我想知道我们可以通过 Composer 安装 Carbon 来使用日期时间函数 php 日期时间函数和 Carbon 哪个更快 我对您的评论做了一些测试 比较了 DateTi
  • 如何证明2条sql语句是等价的

    我开始用连接和子语句重写一个复杂的 SQL 语句 并获得一个看起来更简单的语句 我通过在相同的数据集上运行并获得相同的结果集来测试它 一般来说 我如何 概念上 证明这两个陈述在任何给定数据集中都是相同的 我建议学习关系代数 正如 Mchl
  • 将 XMM 寄存器压入堆栈

    有没有办法将打包双字整数从 XMM 寄存器推送到堆栈 然后在需要时将其弹出 理想情况下 我正在寻找通用寄存器的 PUSH 或 POP 之类的东西 我已经检查了英特尔手册 但我要么错过了命令 要么没有 或者我是否必须将值解压到通用寄存器然后推

随机推荐

  • 如何将外部文件作为类似于代码块的 Sphinx 文档包含在内?

    如何将外部文件作为类似于代码块的 Sphinx 文档包含在内 我怎样才能让它设置语法颜色的样式 在这里找到它 https www sphinx doc org en master usage restructivetext directiv
  • 从 GitHub 加载 Maven 依赖项 [重复]

    这个问题在这里已经有答案了 如何从 GitHub 存储库添加 Java 库 该库使用 Maven 作为构建系统 作为我的 Maven 项目的依赖项 我可以在不下载和编译库的情况下做到这一点吗 现在您可以使用以下命令从 GitHub 存储库导
  • 使用 sox splice 淡入淡出一组音频文件

    我可以使用 SoX 连接和交叉淡入淡出两个音频文件 如下所示 sox file1 wav file2 wav outfile wav splice q soxi D file1 wav 0 5 其中 soxi 替换是获取 file1 的持续
  • 如何根据整数变量的值动态创建许多标签和文本框?

    当我们知道 n 的值时 例如单击 显示 按钮后 有什么方法可以动态创建和显示带有 n 个相应文本框的 n 个标签 如果有任何事情让您不明白我的问题 请告诉我 谢谢你 我正在使用 VS C Express 2010 Windows 窗体 我将
  • MSXML2.XMLHTTP 请求验证在 ASP Classic 中输入的 URL

    预先感谢您收到的任何帮助 我想让我们的客户端在文本字段中输入 URL 然后检查该 URL 是否存在并有效 我想检查 3 种可能的结果 状态 200 正常 状态 500 服务器错误 或者状态为 404 未找到页面 在 ASP classic
  • 如何修改此指令,以便一旦输入可见,除非单击 x,否则它不会被隐藏?

    http plnkr co edit fXo21LnphHZ3qWnuEMFt p preview http plnkr co edit fXo21LnphHZ3qWnuEMFt p preview 现在 如果您单击输入之外的任何位置 则
  • 在没有主机访问权限的情况下更改 DotNetNuke 中的

    我需要更改 DotNetNuke 网站的标题 我有管理员访问权限 但没有主机访问权限 我还可以通过FTP访问网站的文件目录 我可以更改索引页的标题吗 如果您正在谈论在 文档部分 您可以在页面设置中逐页进行设置 从全局角度来看 没有真正的方法
  • 检查在执行单元测试期间是否附加了调试器

    如果调试器附加到当前测试执行 是否有方法检查 JUnit 代码 在 NET C 中我知道这是可能的Debugger IsAttached 用例是在附加调试器时更改或完全禁用测试超时 因为如果您只有大约 15 秒 定义的超时 来调试测试 这会
  • 在 Java 中通过 CrossOrigin 注解或在 Spring-Config XML 中使用 Spring 属性

    我在Spring中使用CrossOrigin注释 现在我想将属性作为值注入到注释中 我无法让这个工作 现在我像这样访问我的财产 Value settings cors origin String cors origin 我想将此属性注入到
  • Bitbucket符号(箭头)含义

    箭头是什么意思 我对 git 或 bitbucket 并不陌生 但我认为我可能在最初的提交中搞砸了一些事情 我需要帮助来解决这个问题 我的本地存储库中的文件夹不是空的 而是将其拉到该文件夹 所在的另一个位置 是链接吗 不在我的本地仓库上 该
  • Angular NgRx - 继续轮询仅第一次调用的服务的效果

    我有一个应用程序 我刚刚添加了 NgRX 我希望使用效果来打开和关闭轮询 示例大纲 我跟着这个帖子 https bbonczek github io jekyll update 2018 03 01 polling with ngrx ht
  • Clickonce部署到多个环境

    我有一个 WPF 应用程序 想通过 ClickOnce 部署给我们的用户 我们有四种环境 系统测试 用户测试 并行生产和生产 每个都需要一个不同的配置文件 其中包含服务器名称和特定于环境的其他内容 因此它们不能全部使用相同的代码库 大部分代
  • AudioClip 的频率和音调关系 - Unity3D

    我正在尝试仅使用 6 个音频剪辑来重新创建吉他的完整音域 我在想有一种方法可以设置音频剪辑的频率 但audio Frequency仅返回基于压缩格式的音频频率 而不是实际的音调 我知道我可以阅读 GetSpectrumData 但该解决方案
  • 在 R 中,我们如何向 kable() 表添加重要性星星?

    使用knitr kable 函数通过rmarkdown创建 doc表 我们如何从给定的数据帧 df b 添加 重要性星星符号 i e cutpoints c 0 001 01 05 1 1 symbols c 接近存储在另一个数据帧 df
  • Spring Boot 单元测试自动装配

    我有以下课程 应用和配置类 package mypackage service import mypackage service util MyUtility import org springframework boot SpringAp
  • Charles proxY:在 https 上重写不起作用

    我正在使用 Charles Proxy 重写网站上的代码 只是为了测试客户的网站 重写适用于除 https 网站之外的所有网站 Charles 可以选择协议 http 或 https 但这也不起作用 每次重写都在 http 上运行良好 而不
  • Firebase 查询 - 嵌套数据

    我正在尝试查询 firebase 中的一些分层数据 我在弄清楚如何查询以下数据结构时遇到了一些困难 orgs KBFXBBEyvgtfqMvU4pi name ACME 123 owner K9IPqIUIuEFzLS0f Pe users
  • 如何测试 Django 测试用例中是否记录了特定日志消息?

    我想确保代码中的某个条件会导致日志消息写入 django 日志 我如何使用 Django 单元测试框架来做到这一点 是否有地方可以检查记录的消息 类似于检查已发送的电子邮件 我的单元测试扩展了django test TestCase 使用m
  • 可滚动弹性盒中的多种背景颜色

    我有一个flexbox flex direction row 具有 2 列内容和固定高度 我希望左栏和右栏分别有红色和蓝色背景 如果任一列溢出 则flexbox的滚动条出现 溢出的部分仍然是红色 蓝色 如果列的内容高度小于flexbox的高
  • 预取指令是否需要在退出之前返回结果?

    在最新的 Intel 和 AMD CPU 上 已执行但请求的行尚未到达指定缓存级别的预取指令是否仍会退出 也就是说 预取的退休是 阻塞 的 因为它看起来对于加载来说是 阻塞 的 还是非阻塞的 关于英特尔处理器 没有 Intel优化手册第7