*移动消除*插槽在 Intel CPU 中如何工作?

2024-01-11

安德烈亚斯·阿贝尔和简·雷内克讨论移动消除 in 他们的论文描述了 uCA https://dl.acm.org/doi/pdf/10.1145/3524059.3532396:

4.1.4 移动消除。 [...] 然而,这一招消除并不总是成功的。 [...] 我们开发了微基准,使用这些计数器来 分析移动消除何时成功。 [...]
以下模型与我们的观察一致。处理器 跟踪被多个使用的物理寄存器 建筑登记册。我们说每个这样的物理寄存器占用一个消除槽。淘汰槽位后再次释放 相应的寄存器已被覆盖。* 的数量 一个周期内可以消除的移动指令取决于两者 可用淘汰槽的数量,以及 上一周期成功淘汰。

我对我不明白的部分进行了强调。

我认为给定的物理寄存器只能由单个架构寄存器使用,从重命名到退出。我认为文本的含义暗示了其他情况,所以我正在努力理解移动消除槽是如何工作的(此时甚至寄存器重命名实际上是如何工作的)。


mov 消除的要点在于,不是分配一个新的 PRF 条目(物理寄存器文件)并运行 uop 来读取值并将其写入该新条目(例如lea rdx, [rcx+0]会),mov rdx, rcx可以通过让 RDX 的 RAT 条目(寄存器分配表)指向与 RCX 此时相同的物理寄存器号来处理。

因此,整个想法是改变 PRF 条目在某个时刻作为单个架构寄存器的状态的规则。这可能使得跟踪 PRF 条目何时可以被释放、或者当两个架构寄存器都引用相同的物理寄存器时重命名以后的微指令变得更加复杂,或者其他一些复杂情况。

“移动消除槽”是单独的资源,而不是 PRF 条目。它们的存在是为了解决英特尔遇到的任何额外的跟踪问题。当您覆盖目标时,移动消除槽会被释放。mov稍后再说,例如mov ecx, edx / not ecx立即释放所需的任何移动消除资源。

如果没有移动消除,你对它的工作原理是正确的;一个 PRF 条目保存仅写入一个架构寄存器的值,并且是在覆盖该寄存器之前读取该寄存器的任何微指令的输入依赖项。

除了 PRF 条目还有 FLAGS 条件代码的空间之外,因此在类似这样的指令之后add eax, ecx写入 FLAGS 和整数寄存器,RFLAGS 和 RCX 都指向相同的物理寄存器。稍后的指令如mov-即时,not or lea可以覆盖 gp 寄存器,只留下 CF 和 SPAZO 组 FLAGS 指向旧的物理寄存器。指令如cmp, stc, or add [mem], eax写入(部分)FLAGS,但不写入整数寄存器。

但这只是两件事(FLAGS 的单独重命名部分,CF 和 SF/PF/AF/ZF/OF 又名 SPAZO https://stackoverflow.com/questions/49867597/what-is-a-partial-flag-stall),它可能仍然可以引用 phys 寄存器,而不是 GP 整数寄存器。每个 phys reg 可能有 1 位来跟踪它是否仍然被 GP-integer reg 引用,当退役写入 GP-integer 寄存器的 uop 时,退役可以正确释放它们,也许只需检查 RAT 条目的退役状态对于标志。或者,也许每个 PRF 条目都有 3 位,每个 GP 整数、CF 和 SPAZO,作为退出的一种方式,以确定何时可以释放物理寄存器(当它退出一个微指令,该微指令会覆盖最后一个架构引用)它。)

BeeOnRope 建议不要在每个 PRF 条目中进行完整的引用计数(计数器最多可以计数到 15,以防万一)mov ecx, eax / mov edx, eax/ ...),移动消除槽实际上是引用计数。

异或归零总是可以被消除,因为物理零寄存器永远不需要被释放,所以它不需要被引用计数。 (整数和向量的物理零寄存器的存在是从 SnB 系列能够消除零微指令这一事实推断出来的。)


有关的:x86的MOV真的可以“免费”吗?为什么我根本无法重现这个? https://stackoverflow.com/questions/44169342/can-x86s-mov-really-be-free-why-cant-i-reproduce-this-at-all其中提到了英特尔优化手册中提到的一些内容,即希望尽快覆盖寄存器副本的结果,以提高 mov-elimination 的成功率。但至少当时Intel并没有提及涉及哪些CPU资源限制的细节。

Skylake 比 Ivy Bridge 有更多的 mov 消除槽,因为我的测试表明它不会在测试用例中遇到瓶颈,他们用来说明及时覆盖 mov 的好处。

非常不幸的是,英特尔搞砸了 Ice Lake / Tiger Lake,不得不通过微代码更新禁用其 mov-elimination(对于 GP-integer),因为覆盖了mov立即通常意味着它是关键路径延迟的一部分,如果您的代码可能在没有 mov-elimination 的情况下在 CPU 上运行,则与您想要的相反。它在 Alder Lake 和 Rocket Lake 再次发挥作用。

在许多情况下,您很快就会覆盖副本和原始文件,因此可以在几条指令中保持目的地不变。理想情况下,避免长期不修改副本,除非这会花费更多的微指令或使 Ice Lake 上的关键路径延迟更糟。 (例如,如果您保存副本并且只读取它。)下一个中断通常会导致所有寄存器无论如何都被保存/恢复,因此即使对于具有一些长的代码,这也不是一个可以“建立”的问题运行带有许多 mov 消除副本的循环。

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

*移动消除*插槽在 Intel CPU 中如何工作? 的相关文章

  • 为什么 Linux/gnu 链接器选择地址 0x400000?

    我正在 Linux x86 64 上试验 ELF 可执行文件和 gnu 工具链 我已经链接并剥离 手动 Hello World 测试 global start text start mov 1 rax 转换为 267 字节 ELF64 可执
  • x86 asm 反汇编程序库

    是否有任何可从 NET 调用的库 我可以在其中传递二进制数据并将其反汇编为 x86 汇编代码 如果您不介意使用 P Invoke 绑定到非托管 dll 请查看比引擎 http www beaengine org 它是您可能找到的最好的反汇编
  • BOOST_LIKELY 和 __builtin_expect 仍然相关吗?

    我明白所解释的内容here https stackoverflow com questions 7346929 why do we use builtin expect when a straightforward way is to us
  • 使用 gdb 在指定的可执行文件之外单步执行汇编代码会导致错误“无法找到当前函数的边界”

    我在 gdb 的目标可执行文件之外 甚至没有与该目标对应的堆栈 无论如何 我想单步执行 以便我可以验证汇编代码中发生了什么 因为我不是 x86 汇编方面的专家 不幸的是 gdb 拒绝进行这种简单的汇编级调试 它允许我设置并停止在适当的断点上
  • 安装apk时INSTALL_FAILED_NO_MATCHING_ABIS

    我尝试将我的应用程序安装到 Android L Preview Intel Atom 虚拟设备中 但失败并出现错误 INSTALL FAILED NO MATCHING ABIS 这是什么意思 INSTALL FAILED NO MATCH
  • 字大小及其指示

    请参阅下面关于各种指令集架构中的字长以及它与汇编语言的关系的问题 感谢您提供的所有帮助 先说几个事实 如有错误 请指正 处理器架构的字长表示 编辑 其中一些是错误的 请参阅下面 Seva 的帖子 每个寄存器的最大尺寸 每个内存地址的最大尺寸
  • FASM 是否使用 Intel 语法?

    我尝试在 FASM 中编译以下代码 mov DWORD PTR ebp 4 1234567 它给了我一个 无效表达式 错误 但是以下代码有效 mov DWORD ebp 4 1234567 那么 FASM 是否使用 Intel 语法 我假设
  • x86 分页如何工作?

    这个问题旨在填补有关该主题的优质免费信息的真空 我相信一个好的答案将适合一个大的 SO 答案 或者至少适合几个答案 主要目标是为初学者提供足够的信息 以便他们可以自己阅读本手册 并能够理解与分页相关的基本操作系统概念 建议指南 answer
  • 我如何使其解密而不是加密?

    想知道如何从加密代码中获取此代码并使用相同的代码来创建解密 我知道这意味着我必须反转一些指令并重新排序 但我无法弄清楚哪些指令需要重新排序 哪些不需要 编辑 这是完整的函数 可以让事情变得更清晰一些 对堆栈溢出非常陌生 因此对于任何混淆表示
  • x86 汇编中 cmove 指令的用途?

    反汇编可执行文件时我遇到了cmove操作说明 我已经在互联网上搜索过 但我只发现这是一个有条件的移动 如果源和目的地相等mov发生 我还不明白为什么我需要它 因为它不会改变操作数 它的目的是什么 The CMOVcc指令不比较源和目标 它们
  • C#:TurboBoost 激活时如何获取 Intel i 系列 CPU 的当前时钟速度

    我知道有可能获得此信息 Intel 自己的 TurboBoost 侧边栏小工具似乎使用 ActiveX 控件来确定 TurboBoost 处于活动状态时 i3 i5 i7 CPU 的当前时钟速度 但是 我想在 C 中以编程方式执行此操作 从
  • 如何在汇编程序中使用 C 库?

    我想知道如何用汇编语言编写文本编辑器 但现代操作系统需要 C 库 特别是对于它们的窗口系统 我找到了这个page http pengu1n is programmer com posts 8304 html 这对我有很大帮助 但我想知道是否
  • 哪种架构称为非均匀内存访问(NUMA)?

    根据wiki http en wikipedia org wiki Non uniform memory access 非均匀内存访问 NUMA 是一种用于多处理的计算机内存设计 其中内存访问时间取决于相对于处理器的内存位置 但尚不清楚它是
  • 英特尔® 事务同步扩展新指令 (TSX-NI) 与英特尔 TSX 有何不同?

    我在Intel的页面上找到了 https ark intel com products 97123 Intel Core i5 7500 Processor 6M Cache up to 3 80 GHz https ark intel c
  • 如何获取 VESA BIOS 信息

    我正在跟踪Phil Opp 教程 https os phil opp com 关于用 Rust 编写一个操作系统 在稍微尝试了一下之后 我想在屏幕上显示真实的图形 我发现我应该从使用带有 VESA 的线性帧缓冲区开始 我在 osdev or
  • 为什么当设置为 TLS 选择器时,ES 和 DS 在 64 位内核上最终会归零?

    下面的 32 位程序调用set thread area 2 http linux die net man 2 set thread area在 GDT 中创建一个条目 该条目旨在用于 TLS 通常将结果选择器放入FS or GS并成功使用
  • 为什么 SSE 对齐读取 + 随机播放在某些 CPU 上比未对齐读取慢,而在其他 CPU 上则不然?

    在尝试优化有限差分代码所需的未对齐读取时 我更改了未对齐的负载 如下所示 m128 pm1 mm loadu ps H k 1 进入这个对齐的读取 随机播放代码 m128 p0 mm load ps H k m128 pm4 mm load
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 内联 asm 中不支持的指令“mov”将控制寄存器移动到 uint32_t

    我在 C 函数中使用汇编代码 但海湾合作委员会给出unsupported instruction mov 以下代码的错误 uint32 t faulting address asm volatile mov cr2 0 r faulting
  • 没有 FPU 的处理器中的浮点计算

    是否可以在没有浮点单元的嵌入式处理器中执行浮点运算 是的 您只需要在软件中完成即可 你的编译器可能会提供支持 http gcc gnu org onlinedocs gccint Soft float library routines ht

随机推荐

  • Groovy def l = [1, 2, 3] as BlockingQueue

    如果我写类似的东西def l 1 2 3 as Socket这显然是无稽之谈 我明白了 org codehaus groovy runtime typehandling GroovyCastException Cannot cast obj
  • 创建子类别选择框 onChange

    我正在创建一个类别系统 用户可以从数据库中选择类别 选择后会创建另一个包含该类别子类别的选择框 所以 我的问题是我怎样才能最好地做到这一点 顺便说一句 我正在使用 Laravel 框架 第一类很简单
  • dataGridView默认错误对话框句柄

    我试图隐藏默认的 datagridview 错误对话框 我将这个事件处理程序的代码放入其中 this dataGridView2 DataError new System Windows Forms DataGridViewDataErro
  • Rails 与 bin/rails 之间有什么区别?

    作为大一新生 我遇到了许多不清楚的细节 其中之一是bin 事物 我一直想知道以下之间有什么区别 rails generate and bin rails generate 当我在控制台中运行这些命令时 它们的行为似乎相同 还有rake an
  • 使用 Drools Workbench 和 KIE 服务器的 HelloWorld

    将 KIE Drools Workbench 6 2 0 Final 安装在 JBoss 7 Application Server 本地实例中 将 Kie Server 6 2 0 Final 安装在本地 Tomcat 7 实例中 严格使用
  • 测试 WCF Web 服务?

    我想为 WCF 服务创建一个测试类 我相信 嘲笑 是正确的术语 我不太确定我认为我必须这样做的方式是正确的方式 我已获得 WCF 服务的 URL 例如 http somesite com wcf RealService svc And ht
  • iOS:如何使用 Quartz 测量字符串的宽度和高度?

    在我提出问题之前 这是来自 Apple 的文档 如何使用 Quartz 确定字符串的宽度 如果文本测量对您的应用很重要 那么可以 使用 Quartz 2D 函数计算它们 但是 您可能首先 考虑使用 ATSUI 其优势在于文本布局和 测量 A
  • 是否可以阻止来自 TFS 中某个分支的 Pull 请求?

    我在 TFS 中有一个共享分支 即很多人推送它 我想阻止人们从该共享分支向任何其他分支打开拉取请求 我可以完全控制服务器端 例如 我可以添加服务器端挂钩或安装服务器端扩展 动机 Given 1 在 TFS 中 我们将工作项与提交相关联 但是
  • 调整大小期间不要重新绘制窗口

    我的 QML 应用程序 Qt 5 4 基于Window物品 用户可以调整应用程序的大小 当应用程序调整大小时 应用程序的内容也会分别调整大小 使用onWidthChanged and onHeightChanged 这一切都很好 但为了避免
  • 将函数中的变量传递给 R 中的其他函数变量

    我正在尝试传递一个变量Phyla 这也是感兴趣的 df 列的名称 到其他函数中 但是我收到错误 Error Column税级is unknown 我明白了 在函数中声明您想要使用一次的列会更方便 因为这也会在脚本中重复多次 我尝试过使用OT
  • 在 Java 中缩短已经很短的字符串

    我正在寻找一种方法来尽可能缩短已经很短的字符串 该字符串是主机名 端口组合 可能看起来像 我的域名 se 2121 or 123 211 80 4 2122 我知道由于所需的开销和缺乏重复 对于这么短的字符串来说常规压缩几乎是不可能的 但我
  • 查找由 fmemopen 创建的文件的大小

    我在用着fmemopen创建一个变量FILE fid将其传递给从打开的文件读取数据的函数 在该函数的某处 它使用以下代码来查找文件的大小 fseek fid 0 SEEK END file size ftell fid 这对于常规文件来说效
  • Android:如何在设备上安装apk,而不使用android sdk工具

    我已将我的应用程序构建到签名的 SDK 中 我希望 beta 测试人员能够在他们的设备上安装它 而无需安装和使用 android sdk 工具 我意识到 apk 可以使用命令行工具安装 但希望没有必要 我尝试手动安装它 但失败了 我有一台
  • 去除 Chrome 和 Safari 浏览器中 html5 视频顶部和底部的黑条

    我正在使用 html5 视频 在 FireFox 中它运行良好 但在 chrome 和 safari 中 它显示顶部和底部的粗黑条 如何摆脱这个酒吧 代码
  • 如何正确清理 docker devicemapper 文件夹?

    我有一些关于存储的问题 文件夹 var lib docker devicemapper 占用了我 50 的存储空间 在文件夹中 var lib docker devicemapper mnt 我有很多空文件夹 如何正确清理 docker设备
  • 无法在辅助接口上接收 UDP/IPv6 数据包

    我有以下用于 UDP 服务器的 C 代码 它将绑定到辅助接口 tap0 的 ipv6 地址 context t new context const struct sockaddr listen addr size t addr size c
  • 如何从另一个闪亮模块更新闪亮模块中的输入?

    我有两个闪亮的模块 updateTextInput in the first一 我要更新textInput in the second模块 当按钮从first被点击 我知道这是因为这些模块位于不同的命名空间中 但我不知道如何通信模块 代表如
  • Neo4j 导入本地 CSV 文件

    我正在尝试导入本地 csv 文件 但出现 InvalidSyntax 错误 LOAD CSV WITH HEADERS FROM file C csv user csv 无效输入 第 1 行第 35 列 偏移量 34 从文件中加载带有标题的
  • 开始对计算机以外的其他东西进行编程的最佳方法是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在计算机之外开始编程的最佳方法是什么 我指的不是带有 API 的手机之类的主流产品 请假设具备 C C 的工作知识 我投票给任天堂 DS 不错的
  • *移动消除*插槽在 Intel CPU 中如何工作?

    安德烈亚斯 阿贝尔和简 雷内克讨论移动消除 in 他们的论文描述了 uCA https dl acm org doi pdf 10 1145 3524059 3532396 4 1 4 移动消除 然而 这一招消除并不总是成功的 我们开发了微