选择 EFLAGS 位的概率

Posted

技术标签:

【中文标题】选择 EFLAGS 位的概率【英文标题】:The probability of selected EFLAGS bits 【发布时间】:2018-07-07 11:55:55 【问题描述】:

我们都知道,在查看源代码时,可以安全地假设方向标志是清晰的。方向标志的概率非常低。

我想了解其他标志的概率。这就是为什么我编写了一个测试程序,它单步执行我现有的一些软件,为前 12 个 EFLAGS 位中的每一个递增一个计数器。

结果证实了关于方向标志 (DF) 的假设,并且毫不奇怪地表明溢出标志 (OF) 的概率非常低。

但是其他标志呢?进位标志 (CF)、辅助标志 (AF)、零标志 (ZF) 和符号标志 (SF) 似乎稳定在 25%,但奇偶标志 (PF) 跳出超过 50%。

我想知道为什么 CF、AF、ZF 和 SF 的概率如此之低。

对于 PF,我自己的两分钱解释告诉我,鉴于所有可能的 8 位位模式中奇偶校验和奇偶校验的 50-50 分布经常使用的数字(0 和 -1)偶数奇偶,超过 50% 的可能性是合理的。

【问题讨论】:

很酷的研究,但我真的不确定您的问题是否有实际答案。 @Shift_Left 关于 RTC 中断。我的是一个简单的测试程序。中断处理程序中的所有代码(硬件或软件)都被排除在外,因为陷阱标志在设计上会在进入处理程序时自动清除。 循环是一个示例,其中 CF 和 ZF 通常在最后一次迭代中设置,并填充不影响它们的指令(主要是指针的移动、推送或算术运算)。由于跟踪是在运行时进行的,因此循环降低了 CF 和 ZF 的几率。在进行算术运算时,SF 和 CF 表示人们通常试图避免的“关键”条件。在进行逻辑操作时,几率应该是 50-50。请注意 AF 和 CF 如何具有相似的分数(可能使用 OR/SBB/SUB 设置相同)。但是,我们不能假设值的均匀分布和“标志的影响力”,所以也许期望是错误的? 这是不是每个指令,甚至像mov 这样的指令都不会影响标志?我的想法是,如果你只在指令确实影响它时检查标志,它会更有趣,尽管我不知道为什么它听起来很有趣,以及这样做有什么好处。基本上,如果您在mov 的较大区域内有 CF=1,您会数次,而代码与 CF 内容无关。关于 PF - 我同意,可能仅 0 就足以使其大部分时间超过 50%。 这不是取决于你的程序在做什么,以及你的编译器如何选择做事吗?您在检测哪个编译器以及哪些应用程序?数字实际上很大的扩展精度数学将设置 CF 更多。 uint64_t 的数字不大 通常会清除 CF(我认为)。有符号值越过零将设置 CF,但即使使用有符号类型,实际上也很少有负数。 【参考方案1】:

某些 EFLAGS 位经常被更改的事实仅反映了早期的 Intel 8086 指令(顺便说一句仍然经常使用的指令)旨在无条件更新标志的事实。该设计决策没有得到很好的回报,但它也不会损害现代 x86 设计,直到有人使用标志值。使用标志(作为条件分支的谓词)会在代码流中创建依赖关系,并且可能会影响性能。

如果有两个(三个、四个……)指令因此更新了相同的标志位,但只有最后一个值被第三条指令使用,则可以省略所有先前的标志计算。或者,可以延迟 E​​FLAGS 的重新计算,直到有东西请求了它的实际值。

因此,一个更有趣的问题是使用单个 EFLAG 位的频率。并且有研究可以回答这个问题。

下图取自 Yair Lifshitz 等人。 “Zsim:用于 ISA 设计空间探索的快速架构模拟器”第 3.2.3 节 PDF:

如您所见,没有人关心辅助标志,而进位和零标志会影响代码中的许多决策。其他作者得出了类似的结论,这在例如软件模拟设计,因为它们允许在二进制翻译器和解释器中应用惰性标志评估的重要优化。

【讨论】:

那个设计决策没有得到很好的回报我不会这么说。高性能实现的真正有问题的指令是有条件地更新标志的指令,例如如果计数为 0 时不修改它们的移位。这就是为什么 shl reg,cl 在 Sandybridge 系列上是 3 uops 的原因。无条件写入某些但并非所有标志也是有问题的,例如incadd 之类的指令基本没问题。有关 inc 和 shift 的更多信息,请参阅 INC instruction vs ADD 1: Does it matter? 让大多数指令设置标志实际上对 8086 来说是件好事,我认为,通过避免需要 test ax,ax 或在某些 jcc 指令之前的任何内容来增加代码密度。这仍然是 x86 代码密度的优势。乱序执行确实必须重命名标志以及整数寄存器以避免输出依赖性,但我认为默认情况下并不总是设置标志的 ISA 的乱序实现也会这样做。 (例如 ARM。只有一些 insn 的标志设置版本具有短的 Thumb2 编码,因为冗余标志写入不会影响性能。) @PeterCordes 我不知道旧班次这么糟糕,谢谢!我不认为这对 8086 时代来说是坏事,但现在它是一个令人讨厌的遗产(重命名主要解决它)。

以上是关于选择 EFLAGS 位的概率的主要内容,如果未能解决你的问题,请参考以下文章

英特尔 PIN 工具:获取 EFLAGS 值的踪迹

x86 保留 EFLAGS 位 1 == 0:这怎么会发生?

sde.layers表的eflags字段解析

EFLAGS标志寄存器加深理解

学 Win32 汇编[20]: 洞察标志寄存器

英特尔RFLAGS和POPFQ PUSHFQ?