- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 x86-64 中设置和清除零标志 (ZF) 的最有效方法是什么?
无需具有已知值的寄存器或根本没有任何空闲寄存器即可工作的方法是首选,但如果在这些或其他假设为真时有更好的方法可用,则也值得一提。
最佳答案
ZF=0
这更难。 cmp
在任何两个已知不相等的 regs 之间。或 cmp reg,imm
具有某些 reg 不可能具有的任何值(value)。例如cmp reg,1
与任何已知零寄存器。
一般情况test reg,reg
适用于任何已知的非 0 寄存器值,例如一个指针 .
test rsp, rsp
大概是个不错的选择,甚至 test esp, esp
除非您的堆栈位于跨越 4G 边界的异常位置,否则保存一个字节将起作用。
我没有看到一种在一条指令中创建 ZF=0 而不对某些输入 reg 产生错误依赖的方法。 xor eax,eax
/inc eax
或 dec
如果您不介意破坏寄存器,打破错误的依赖关系,将在 2 个 uops 中完成任务。 ( not
不设置标志,而 neg
只会做 0-0 = 0。)
or eax, -1
寄存器值不需要任何先决条件。 (错误的依赖,但不是真正的依赖,所以你可以选择任何寄存器,即使它可能为零。)它不一定是 -1
,它不会让你得到任何东西,所以如果你能让它变得有用就更好了。
or eax,-1
标志结果:ZF=0 PF=1 SF=1 CF=0 OF=0(AF=未定义)。
如果您需要在循环中执行此操作,显然可以在循环外为其设置,如果您可以将寄存器专用于非零以用于 test
.
ZF=1
破坏性最小:cmp eax,eax
- 但有一个错误的依赖(我假设)并且需要一个后端 uop:不是一个归零习语。 RSP 通常不会有太大变化 cmp esp, esp
可能是一个不错的选择。 (除非强制堆栈同步 uop)。
最高效: xor-zeroing (如 xor eax,eax
使用任何免费寄存器)绝对是 SnB 系列上最有效的方式(与 2 字节相同的成本 nop
,如果需要 REX 则为 3 字节,因为您想将其归零r8d..r15d):1 个前端 uop,零后端 uops 在 SnB 系列上,FLAGS 结果在它发出的同一周期中准备就绪。 (仅在前端停止的情况下相关,或者其他一些情况,其中依赖于它的 uop 在同一周期中发出,并且 RS 中没有任何具有就绪输入的较旧的 uops,否则此类 uops 将具有优先权执行端口。)
标记结果:ZF=1 PF=1 SF=0 CF=0 OF=0(AF=未定义)。 (或使用 sub eax,eax
得到明确定义的 AF=0。实际上,现代 CPU 也选择 AF=0 进行异或归零,因此它们可以以相同的方式解码两个归零习语。Silvermont 仅识别 32 位操作数大小xor 作为归零习语,而不是 sub。)
xor-zero 在所有其他 uarches 上也非常便宜,当然:没有输入依赖性,并且不需要任何预先存在的寄存器值。 (因此不会导致 P6-family register-read 停顿)。因此,它最坏的情况是与您可以在任何其他 uarch 上执行的任何其他操作相关联(它确实需要一个执行单元。)
(在 Pentium M 之前的早期 P6 系列上,xor
-zeroing 不会破坏依赖关系;它只会触发特殊的 al=eax 状态,以避免部分寄存器的东西。但这些 CPU 都不是 x86-64,都是 32-只是一点点。)
无论如何,想要一个归零的寄存器是很常见的,例如作为 sub
0 - x
的目的地复制和否定,所以通过将异或归零放在您需要的地方来利用它来创建一个有用的标志条件。
正如@prl 所建议的,cmp same,same
使用任何寄存器都可以在不干扰值的情况下工作 .我怀疑这不是特殊情况,因为依赖打破了方式 sub same,same
在某些 CPU 上,所以 选择一个“冷”寄存器 .同样是 2 或 3 个字节,1 uop。它可以与 JCC 进行微融合,但那将是愚蠢的(除非 JCC 也是某些其他条件的分支目标?)
标志结果:与异或归零相同。
缺点:
test al, 0
. AL 为 2 个字节,任何其他 8 位寄存器为 3 或 4 个字节。 (REX) + 操作码 + modrm + imm8。原始寄存器值无关紧要,因为
imm8
零保证
reg & 0 = 0
.
1
或
-1
在一个可以销毁的寄存器中,32 位模式
inc
或
dec
将仅在 1 个字节中设置 ZF。但在 x86-64 中,这至少是 2 个字节。对于 64 位模式下的 1 字节指令实际上是有效的并设置了 FLAGS,什么都没有想到。
sbb same,same
可以设置 ZF=CF(不修改 CF),并将 reg 设置为 0(CF=0)或 -1(CF=1)。在推土机系列上,这不依赖于 GP 寄存器,只依赖于 CF,但在其他 uarches 上它不是特殊情况,并且在 reg 上有一个错误的依赖。
test reg,reg
is your best bet . (优于
and reg,reg
或
or reg,reg
,除非您有意重写寄存器以避免 P6 寄存器读取停顿。)
test
或 cmp
没有预先存在的寄存器值,则不可能)。 pushf
/pop rax
并不可怕,但用 popf
写标志非常慢(例如 SKL 上的 1/20c 吞吐量)。它是微编码的,因为像 IF 这样的标志也存在于 EFLAGS 中,并且没有仅条件代码版本或用户空间的特殊快速路径。 (或者也许 20c 是快速路径。)lahf
(FLAGS->AH)/sahf
(AH->FLAGS) 可能很有用,但会错过 OF。 clc
/
stc
/
cmc
指示。 (
clc
与 SnB 系列上的异或归零一样有效。)
关于performance - 在 x86 中设置和清除零标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54499327/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 8年前关闭。 Improve t
暂时忘记能力的定义,只关注能力的“检查”(使用“授权!”),我看到 CanCan 添加了大约 400 毫秒,用于简单地检查用户是否具有特定的能力主题/模型。 这是预期的吗(我假设不是)?或者,有没有可
我正在阅读有关 Swift 的教程 ( http://www.raywenderlich.com/74438/swift-tutorial-a-quick-start ),它预定义为不显式设置类型,因
这主要是由于对 SQL 问题的回答。由于性能原因,有意省略了 UDF 和子查询。我没有包括可靠性并不是说它应该被视为理所当然,但代码必须工作。 性能永远是第一位的吗?提供了许多以性能为主要优先事项的答
我已经编写了一个简单的测试平台来测量三种阶乘实现的性能:基于循环的,非尾递归的和尾递归的。 Surprisingly to me the worst performant was the loop o
我已将 ui-performance 插件应用到我的应用程序中。不幸的是,在开发模式下运行应用程序时它似乎不起作用。例如,我的 javascript 导入是用“vnull”版本呈现的。 例如 不会
我有一个我操作的 F# 引用(我在各处添加对象池以回收经常创建和删除的短期对象)。我想运行结果报价;现在我使用了 F# PowerPack,它提供了将引用转换为表达式树和委托(delegate)的方法
我正在尝试在 Spark 服务器上运行 SparklyR 库中的机器学习算法。 1 个簇 8 核 24G内存 Ubuntu 16.04 星火2.2 独立配置 1名师傅/2名 worker 每个执行器的
我有一个数据库(准确地说是在 postgres 上运行),具有以下结构: user1 (schema) | - cars (table) - airplanes (table, again) .
我的应用程序在我的 iPad 上运行。但它的表现非常糟糕——我的速度低于 15fps。谁能帮我优化一下? 它基本上是一个轮子(派生自 UIView),包含 12 个按钮(派生自 UIControl)。
在完成“Scala 中的函数式编程原则”@coursera 类(class)第 3 周的作业时,我发现当我实现视频类(class)中所示的函数联合时: override def union(tha
我正在重构我的一个 Controller 以使其成为一项服务,我想知道不将整个服务容器注入(inject)我的 Controller 是否会对性能产生影响。 这样效率更高吗: innova.path.
我有一个要显示的内容很大的文件。例如在显示用户配置文件时, 中的每个 EL 表达式需要一个 userId 作为 bean 的参数,该参数取自 session 上下文。我在 xhtml 文件中将这个 u
我非常了解 mipmapping。我不明白(在硬件/驱动程序级别)是 mipmapping 如何提高应用程序的性能(至少这是经常声称的)。在执行片段着色器之前,驱动程序不知道要访问哪个 mipmap
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: What's the (hidden) cost of lazy val? (Scala) Scala 允许定义惰
一些文章建议现在 build() 包含在 perform() 本身中,而其他人则建议当要链接多个操作时使用 build().perform()一起。 最佳答案 build() 包含在 perform(
Postgres docs说 For best optimization results, you should label your functions with the strictest vol
阅读Zero-cost abstractions看着 Introduction to rust: a low-level language with high-level abstractions我尝
我想在 MQ 服务器上部署 SSL,但我想知道我当前的 CPU 容量是否支持 SSL。 (我没有预算增加 CPU 内核和 MQ PVU 的数量) 我的规范: Windows 2003 服务器 SP2,
因此,我在 Chrome 开发者工具 的性能 选项卡内的时间 部分成功地监控了我的 React Native 应用程序的性能。 突然在应用程序的特定重新加载时,Timings 标签丢失。 我已尝试重置
我是一名优秀的程序员,十分优秀!