如果您的程序+库不包含 SSE 指令,那么使用 VZEROUPPER 有用吗?

2024-04-14

我明白使用它很重要VZEROUPPER混合 SSE 和 AVX 代码时,但如果我只使用 AVX(和普通 x86-64 代码)而不使用任何旧版 SSE 指令怎么办?

如果我从未在代码中使用单个 SSE 指令,是否有任何性能原因导致我需要使用VZEROUPPER?

这是假设我没有调用任何外部库(可能正在使用 SSE)。


也可以看看首次使用 AVX 256 位向量会减慢 128 位向量和 AVX 标量运算 https://stackoverflow.com/questions/66874161/first-use-of-avx-256-bit-vectors-slows-down-128-bit-vector-and-avx-scalar-ops回复:如果任何上层脏了,则将 128 位 AVX 操作隐式扩展到 256 位。 (包括为了“轻型”与“重型”涡轮限制 https://stackoverflow.com/questions/56852812/simd-instructions-lowering-cpu-frequency)。这可能是使用的一个原因vzeroupper,特别是如果程序的某些区域使用 256 位向量(尤其是“轻型”指令,例如除乘法之外的整数内容),而其他区域则大量使用 128 位 FMA。没有vzeroupper,128 位 FP 数学指令可能会降低您的最大睿频,就像您一直在使用繁重的 256 位指令一样。 (如果你无论如何都这样做,也许没什么大不了的)。


你是对的,如果你的整个程序不使用any写入的非 VEX 指令xmm寄存器,你不需要vzeroupper以避免状态转换惩罚。

请注意,非 VEX 指令可能潜伏在 CRT 启动代码和/或动态链接器或其他非常不明显的地方。

也就是说,非 VEX 指令在运行时只能造成一次性惩罚。反之则不然:一条 VEX-256 指令通常可以生成非 VEX 指令(或仅使用该寄存器)程序的其余部分很慢 https://stackoverflow.com/questions/41303780/why-is-this-sse-code-6-times-slower-without-vzeroupper-on-skylake/41349852#41349852.


There's 混合 VEX 和 EVEX 时没有惩罚 https://stackoverflow.com/questions/46080327/what-is-the-penalty-of-mixing-evex-and-vex-encoded-scheme,所以不需要使用vzeroupper there.


在 Skylake-AVX512 上:vzeroupper or vzeroall是在弄脏 ZMM 寄存器后恢复 max-turbo 的唯一方法,假设您的程序仍在 xmm/ymm0..15 上使用任何 SSE*、AVX1 或 AVX2 指令。

也可以看看Skylake 是否需要 vzeroupper 来让 Turbo 时钟在仅读取 ZMM 寄存器、写入 k 掩码的 512 位指令后恢复? https://stackoverflow.com/questions/58568514/does-skylake-need-vzeroupper-for-turbo-clocks-to-recover-after-a-512-bit-instruc- 仅仅读取 zmm 不会导致这种情况。

发表者聊天中@BeeOnRope https://chat.stackoverflow.com/transcript/message/43768745#43768745:

AVX-512 指令对周围代码有一个新的、非常糟糕的影响:一旦执行 512 位指令(可能除了不写入 zmm 寄存器的指令),核心就会进入“上 256 脏状态” 。在此状态下,任何后续标量 FP/SSE/AVX 指令(任何使用 xmm 或 ymm 寄存器的指令)都将在内部扩展至 512 位。这意味着处理器将被锁定到不高于 AVX Turbo(所谓的“L1 许可证”),直到发布 vzeroupper 或 vzeroall 为止。

与早期 AVX 和旧版非 VEX SSE(仍然存在于 Skylake Xeon 上)的“脏上 128”问题不同,这会由于频率较低而减慢所有代码的速度,但不会出现“合并 uops”或错误依赖关系或类似的事情:只是较小的操作被有效地视为 512 位宽,以实现零扩展行为。

关于“写下半部分......” -不,它是一个全局状态,并且只有 vzero让你摆脱困境*。即使您弄脏了 zmm 寄存器但对 ymm 和 xmm 使用了不同的寄存器,也会发生这种情况。即使唯一的脏指令是像这样的归零惯用法,也会发生这种情况vpxord zmm0, zmm0, zmm0. 但写入 zmm16-31 时不会发生这种情况.

他的描述actually将所有向量运算扩展到 512 位并不完全正确,因为他后来证实这不会降低 128 和 256 位指令的吞吐量。但我们知道,当 512 位微指令运行时,端口 1 上的矢量 ALU 会关闭。 (因此,通常可通过端口 0 和 1 访问的 256 位 FMA 单元可以组合成一个 512 位单元,用于所有 FP 数学、整数乘法以及可能的其他一些内容。某些 SKX Xeon 在端口上有第二个 512 位 FMA 单元5、有些则不然。)


仅使用 AVX1 / AVX2 后的最大涡轮增压(包括像 Haswell 这样的早期 CPU):如果一段时间没有使用执行单元的上半部分,则机会性地关闭它们(有时允许更高的 Turbo 时钟速度)取决于最近是否使用过 YMM 指令,而不是取决于是否使用过 YMM 指令。上半部分是否脏。所以据我所知,vzeroupper does not对于 256 位最大睿频较低的 CPU,在使用 AVX1 / AVX2 后帮助 CPU 更快地取消时钟速度。

这与英特尔的 Skylake-AVX512 (SKX / Skylake-SP) 不同,其中 AVX512 有点“固定”。


VZEROUPPER可能会进行上下文切换slightly cheaper

因为CPU仍然知道ymm-upper状态是干净的还是脏的。

如果干净的话我觉得xsaveopt https://github.com/HJLebbink/asm-dude/wiki/XSAVEOPT or xsavec可以更紧凑地写出 FPU 状态,而无需存储全零的上半部分(只需设置一点表明它们是干净的)。注意在 SSE/AVX 的状态转换图中 https://stackoverflow.com/questions/41303780/why-is-this-sse-code-6-times-slower-without-vzeroupper-on-skylake/41349852#41349852 that xsave / xrstor是图片的一部分。

一个额外的vzeroupper仅当您的代码不使用任何 256b 指令时才值得考虑long在此之后的时间,因为理想情况下,在下次使用 256 位向量之前,您不会进行任何上下文切换/CPU 迁移。

这在 AVX512 CPU 上可能不太适用:vzeroupper / vzeroall https://www.felixcloutier.com/x86/vzeroall#vzeroall--vex-256-encoded-version-不要碰ZMM16..31,只碰ZMM0..15。所以之后你仍然可以有很多脏状态vzeroall.


(理论上合理):脏的上半部分可能会占用物理寄存器(尽管 IDK 没有任何证据证明这在任何真实的 CPU 上都是正确的)。如果是这样,它将限制 CPU 寻找指令级并行性的无序窗口大小。 (ROB 大小是另一个主要限制因素,但 PRF 大小可能是瓶颈 http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/.)

这在 Zen2 之前的 AMD CPU 上可能是正确的,其中 256b 操作被分成两个 128b 操作。 YMM 寄存器在内部作为两个 128 位寄存器进行处理,例如vmovaps ymm0, ymm1以零延迟重命名低 128,但上半部分需要一个微指令。 (看阿格纳·福格的微建筑 pdf http://agner.org/optimize/)。未知是否vzeroupper不过,实际上可以放弃上半部分的重命名。 AMD Zen 上的清零习惯(与 SnB 系列不同)仍然需要后端 uop 来写入寄存器值,即使对于 128b 低半部分也是如此;只有 mov-elimination 可以避免后端 uop。因此可能不存在可以重命名上层的物理零寄存器。

实验中ROB尺寸/PRF尺寸博客文章 http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/不过,表明 Sandybridge 中的 FP 物理寄存器文件条目是 256 位。vzeroupper不应该在带有 AVX/AVX2 的主流 Intel CPU 上释放更多寄存器。 Haswell 式的转换惩罚足够慢,以至于它可能会耗尽 ROB 来保存或恢复上部到未重命名的单独存储,而不是使用有价值的 PRF 条目。

Silvermont 不支持 AVX。它使用单独的退休登记档案 https://www.realworldtech.com/silvermont/4/对于架构状态,因此无序 PRF 仅保存推测的执行结果。因此,即使它确实支持 128 位半部的 AVX,上半部脏的陈旧 YMM 寄存器也可能不会占用重命名寄存器文件中的额外空间。

KNL(Knight's Landing / Xeon Phi)是专门为运行 AVX512 而设计的,因此推测其 FP 寄存器文件具有 512 位条目。它基于 Silvermont,但核心的 SIMD 部分不同(例如,根据 Agner Fog 的说法,它可以重新排序 FP/向量指令,而 Silvermont 只能推测性地执行它们,但不能在 FP/向量管道内重新排序)。尽管如此,KNL 也可能使用单独的退休寄存器文件,因此即使 ZMM 能够分割 512 位条目来存储两个 256 位向量,脏 ZMM 上层也不会消耗额外的空间。这不太可能,因为 KNL 上仅 AVX1/AVX2 的较大乱序窗口不值得花费晶体管。

vzeroupper在 KNL 上比主流 Intel CPU 慢得多(64 位模式下每 36 个周期一个),所以你可能不想使用,尤其是为了微小的上下文切换优势。


在 Skylake-AVX512 上,证据支持矢量物理寄存器文件为 512 位宽的结论。

某些未来的 CPU 可能会将物理寄存器文件中的条目配对来存储宽向量,即使它们通常不会像 AMD 对 256 位向量那样解码为单独的微指令。

@神秘报道 https://stackoverflow.com/questions/48892733/can-avx2-compiled-program-still-use-32-registers-of-an-avx-512-capable-cpu#comment84791900_48892842使用 YMM 与 ZMM 的长 FP 依赖链的代码会意外变慢,但其他方面的代码相同,但后来的实验不同意以下结论:当高 256 位脏时,SKX 对 ZMM 寄存器使用 2x 256 位寄存器文件条目。


Ice Lake/Sa​​pphire Rapids 上的 AVX-512 和物理寄存器

https://chipsandcheese.com/2023/01/15/golden-coves-vector-register-file-checking-with-official-spr-data/ https://chipsandcheese.com/2023/01/15/golden-coves-vector-register-file-checking-with-official-spr-data/

[...]
虽然在服务器 Ice Lake 上进行的测试表明英特尔的机制远没有那么复杂。相反,核心只是记住上一组 ZMM 寄存器是否正在使用。如果您使用 AVX-512 引入的任何额外寄存器(即 ZMM16 到 31),Ice Lake 会保留另外 16 个寄存器来保存已知良好状态。无论你触摸其中一个还是全部,都没有关系。 Golden Cove 是 Ice Lake 的继承者,可以使用类似的机制。

... 因此,Zen 4 没有采用与 Ice Lake 相同的寄存器保存优化。

但不幸的是,我不认为vzeroupper / vzeroall可以帮忙解决这个问题;它不会影响 ZMM16..31,因此无法将它们恢复到“干净”状态并释放那些额外的 16 个物理寄存器以用于乱序执行。

如果我理解正确的话,手动将它们异或归零will阻止他们使用物理寄存器(vpxord xmm16, xmm16, xmm16通过xmm31);要么有一个额外的位来指示全零,要么有一个物理零寄存器,重命名器可以将它们指向。但可能仍然有 16 个额外的 PRF 条目保留用于退休状态,即使实际的 RAT 条目没有指向它们。

随着他们归零,xsave/xrstor上下文切换时可能会回到 zmm16-31-unused 状态。 CPU 大概必须能够以某种方式返回到该状态,而不是冷启动或进入深度睡眠状态。

该文章还有一些其他有趣的发现,例如 320 个向量 PRF 条目中只有 220 个能够保存 512 位结果。因此,只要足够,就使用 256 位指令(例如,从缩小到 256 位开始进行水平缩减)可以帮助乱序执行器看得更远。

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

如果您的程序+库不包含 SSE 指令,那么使用 VZEROUPPER 有用吗? 的相关文章

  • SQL 与 LINQ 性能 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • 加载实体实例需要超过 1 秒

    我在EF中遇到了一件有趣的事情 如果我们使用基础实体获取子实体 则加载实体需要更多时间 我的模型看起来像这样 public abstract class BaseDocument public Guid Id get set public
  • 我可以在 pandas 中执行动态行累加吗?

    如果我有以下数据框 如下导出 df pd DataFrame np random randint 0 10 size 10 1 0 0 0 1 2 2 8 3 1 4 0 5 0 6 7 7 0 8 2 9 2 有没有有效的方法cumsum
  • 在二维平面中找到距离 P 点最近的 K 个点

    资料来源 亚马逊面试问题 解决方案1制作大小为 K 的堆并按最小距离收集点O NLogK 复杂 解决方案2 取大小为 N 的数组并按距离排序 应该使用QuickSort 霍尔修改 取前 K 点作为答案 这太复杂了 NlogN 但可以优化到近
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • CSS:它渲染“ul > li”比“ul li”更快吗?

    正如我从少数人那里听说的那样 使用 gt 而不是 使渲染速度更快 slide hover gt div gt span border color c8c8c8 OR slide hover div span border color c8c
  • 在 O(n) 时间内运行的指数乘法算法?

    我正在读一本算法教科书 我被这个问题难住了 假设我们要计算值 x y 其中 x 和 y 为正数 分别具有 m 和 n 位的整数 解决该问题的一种方法是执行 y 1 乘以 x 你能给出一个仅使用 O n 乘法步骤的更有效的算法吗 这会是一个分
  • 避免 VBCSCompiler 对 Roslyn 支持的 ASP.NET Razor MVC 视图造成性能影响?

    为了在 MVC5 上的 Razor 视图中支持 C 6 我们通过 web config 打开了 Roslyn 编译器平台
  • 使用循环计算 Python 字典中元素的有效方法

    我有一个值列表 我希望在循环期间计算每个类的元素数量 即 1 2 3 4 5 mylist 1 1 1 1 1 1 2 3 2 2 2 2 3 3 4 5 5 5 5 mydict dict for index in mylist mydi
  • 在 R 中替换数据帧中最低列表值的最有效方法

    我有一个数据框 df 其中包含为每个受试者记录的数字列表 向量 用于测试项目的两次重复 subj item rep vec s1 1 1 2 1 4 5 8 4 7 s1 1 2 1 1 3 4 7 5 3 s1 2 1 6 5 4 1 2
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • 给定两个(大)点集,我如何有效地找到彼此最接近的点对?

    我需要解决一个计算问题 该问题归结为搜索两个集合之间最接近的点对 问题是这样的 给定欧几里德空间中的一组点 A 和一组点 B 找到所有对 a b 使得 b 是 B 中与 a 最近的点 a 是 A 中与 b 最近的点 集合 A 和 B 的大小
  • Android 在 ROOM 数据库中插入大量数据

    我有大约 10 个模型 每个模型都有超过 120K 行和 90 列的记录 其中包含双数组值 在 Room 中插入任何模型都需要超过 125 130 秒 任何人都可以建议我需要做什么才能使用一些批量插入技术来保存所有这些 120K 该技术大约
  • 我想优化这个短循环

    我想优化这个简单的循环 unsigned int i while j 0 j is an unsigned int with a start value of about N 36 000 000 float sub 0 i 1 unsig
  • 如何提高QNX6下Eclipse IDE的性能

    我们在 VMWare 环境中通过 QNX6 运行 Eclipse 速度非常慢 Eclipse 是这样启动的 usr qnx630 host qnx6 x86 usr qde eclipse eclipse data root workspa
  • Python:多重分配与单独分配速度

    我一直在寻求从我的代码中挤出更多的性能 最近 在浏览时这个 Python 维基页面 https wiki python org moin PythonSpeed 我发现了这个说法 多重分配比单独分配慢 例如 x y a b 比 x a y
  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • HTML if 语句在 CDN 失败时加载本地 JS/CSS

    当从 CDN 或任何外部服务器加载 CSS JS 文件时 有可能 即使概率很低 由于外部故障而丢失该文件 在这种情况下 html 页面将因缺乏适当的 CSS 和 JS 而被损坏 有没有一种实用的方法可以在 CDN 故障时加载本地版本 IF

随机推荐

  • css位置固定根本不起作用

    我正在寻找一个页脚类型的东西布莱克霍利网站 http www blakehawley com它有一些不同的链接等 它应该是横幅样式 我的意思是它应该停留在底部并被修复 div 是 菜单 这是我的 HTML
  • 当 merge.ff = only 时如何挤压合并?

    首先 我有我的merge ff设置为only as in git config global merge ff only 我这样做是因为我不希望 git 在没有先与我检查的情况下进行非快进合并 这是一个很好的保障 确保我有机会做一些除了创建
  • ServiceStack AppHost 是单例吗?

    我一直在评估 ServiceStack 到目前为止 我已经被说服了 但我有一个要求 think将会破坏交易 我基本上需要多个 AppHost 派生的实例 第一个运行良好 但其余的则失败 因为 AppHostBase Instance 已被设
  • 执行 tail -F 直到匹配模式

    我想做一个tail F在文件上直到匹配模式 我找到了一种使用方法awk 但恕我直言 我的命令并不是很干净 问题是我need由于某些限制 只能用一行来完成 tail n 0 F tmp foo awk W interactive if 1 E
  • 使用支持库 v21 设置 SearchView Widget 的样式

    我正在尝试使用新的 AppCompat v21 设计 SearchView 小部件的样式 但我遇到了一些问题 无论我在 suggestionRowLayout 属性上设置什么布局 它都不会执行任何操作 SearchView 的建议下拉列表保
  • R中5个排名的频率统计

    假设我有 5 件商品A B C D E并让受访者对它们进行排名 数据看起来像这样 gt df rank1 rank2 rank3 rank4 rank5 1 A B C D E 2 A C B D E 3 C A B E D 4 B A C
  • 如何避免 jasmine 在不同环境下出现较长的相对路径(../../../)?

    我目前正在开发一个项目 我想在不同的环境中进行测试 包括 node js 和带有 karma selenium 的不同浏览器 以避免兼容性问题 我想我会在浏览器中使用browserify 但我还不熟悉它 我有一个嵌套的测试目录 如下所示 r
  • verilog 中的案例陈述

    我遇到了优先级编码器设计 并找到了一种使用 case 语句来实现它的新方法 唯一令人困惑的是 case语句是否优先考虑case 例子 case 1 b1 A 3 Y lt 4 b1000 A 2 Y lt 4 b0100 A 1 Y lt
  • toDataURL 不是函数

    我正在尝试为画布生成一个网址 以下是我遵循的步骤 var can document getElementsByTagName canvas var src can toDataURL image png 当我尝试在 firebug 上运行上
  • 导航架构:如何在不使用clearTask的情况下管理正确的导航,因为它已被弃用

    当使用导航架构时here https issuetracker google com issues 116831650 here https issuetracker google com issues 80338878不推荐使用clear
  • 蓝牙文件发送

    我是蓝牙开发的新手 我发现了 32netfeet 现在我可以搜索附近的蓝牙设备并连接到它们 但如何发送文件 例如 SendTest txt 我尝试使用 OBEX 的 buttonclick 事件 但我不明白这是我的示例代码 using In
  • powershell 中的 DLLImport 用于使用相对路径访问 C 风格 32 位 API

    我想用powershell中的相对路径导入dll 下面是我尝试导入 dll 的代码片段 dirpath split path MyInvocation MyCommand Definition testDllPath dirpath Tes
  • SQL Server Management Studio (SSMS):最近的文件 (MRU) 菜单过于缩写而无法使用

    我在查找要编辑的正确 SQL 文件时遇到问题最近的文件 有时称为 MRU 最新版本的 SSMS 中的列表 我使用的是 18 5 我的文件具有相似的名称或相同的名称 但位于不同的文件夹中 这在 SSMS 的早期版本 我认为是 18 之前的版本
  • JavaScript 正则表达式匹配平衡结构而不关心不平衡结构

    我正在开发一个基于 JavaScript 的项目 该项目涉及一个基本的 Bash 启发的脚本系统 并且我正在使用正则表达式将行分隔成 多种类型的 标记 一种这样的令牌类当然是递归的 构造 该结构可以任意嵌套 我正在尝试设计一个 JavaSc
  • tkinter.ttk.Treeview根节点图标/图像不出现

    Problem 我无法让图标图像出现在 tkinter ttk Treeview 中根节点旁边 下面是我使用的测试代码 它执行时没有错误 但图像没有出现在根节点的左侧 我尝试过使用图像文件的完整路径名 但这不起作用 另外 我尝试使用 PIL
  • HTML5 Canvas 动画偶尔出现抖动/犹豫/卡顿

    在 Firefox 11 中 我在使用 HTML5 画布和翻译的一些基本动画中偶尔遇到抖动 犹豫 口吃的情况 请看下面的例子 http jsfiddle net ACRdx http jsfiddle net ACRdx 上面示例中的配置似
  • PrimeFaces 文件上传

    我正在一个项目中使用 jsp Servlet 并且决定使用 PrimeFaces 迁移到 JSF 我在尝试使用 PrimeFaces 文件上传控件上传文件时遇到了问题 然后当我将其配置到 web xml 中时 它运行良好 问题就来了现在所有
  • 警告:函数作为 React 子项无效。 (反应原生)

    我收到错误 警告 函数作为 React 子项无效 我正在编写一个 React Native 应用程序 interface RegisterScreenProps navigation NavigationContainerRef const
  • jquery文本区域长度计数?

    我有一个文本区域字段 当用户在该字段中输入一些文本时 我需要提供有关字数的信息 该字段的长度应为 500 个字符 最初它必须显示 最少字符数 100 0 of 500 0 of 500 必须为红色 一旦用户输入了字符 也需要更新计数 一旦用
  • 如果您的程序+库不包含 SSE 指令,那么使用 VZEROUPPER 有用吗?

    我明白使用它很重要VZEROUPPER混合 SSE 和 AVX 代码时 但如果我只使用 AVX 和普通 x86 64 代码 而不使用任何旧版 SSE 指令怎么办 如果我从未在代码中使用单个 SSE 指令 是否有任何性能原因导致我需要使用VZ