当前位置: 首页 > 知识库问答 >
问题:

什么是偏旗档?

子车征
2023-03-14

当读取标志时,如果发生了部分标志停滞,则会发生部分标志停滞。P4从来没有部分标志档,因为它们从来不需要合并。相反,它有虚假的依赖关系。几个答案/评论混淆了术语。他们描述了一个假依赖,但称之为部分标志停滞。这是一种减速,因为只写了一些标志,但术语“部分标志停滞”是在SNB之前的英特尔硬件上,当部分标志写必须合并时发生的情况。Intel SNB系列CPU插入一个额外的uop来合并标志而不会停滞。Nehalem和早期失速~7个循环。我不确定对AMD CPU的惩罚有多大。

我觉得我还不明白什么是“局部旗帜摊位”。我怎么知道已经发生了?除了有时读取标志之外,还有什么触发事件?合并标志是什么意思?在什么情况下“写了一些标志”但不发生部分标志合并?我需要了解什么关于旗子摊档来理解它们?

共有1个答案

况喜
2023-03-14

一般说来,当使用标志的指令读取最近的标志设置指令未写入的一个或多个标志时,就会发生部分标志停滞。

因此,像inc这样只设置一些标志(它不设置cf)的指令本身不会导致部分停顿,但如果后续指令读取inc未设置的标志(cf)(没有任何设置cf标志的中间指令),则会导致停顿。这也意味着写入所有感兴趣标志的指令永远不会出现在部分停顿中,因为在执行标志读取指令时,当它们是最近的标志设置指令时,它们一定已经写入了消耗的标志。

因此,通常,静态地确定是否会发生部分标志停滞的html" target="_blank">算法是查看使用这些标志的每个指令(通常是JCC族和cmovcc以及一些特殊指令,如ADC),然后向后查找设置任何标志的第一条指令,并检查它是否设置了消费指令读取的所有标志。如果没有,将出现部分标志停滞。

后来的架构,从Sandy Bridge开始,本身不会出现部分标志停滞,但在某些情况下仍然会受到惩罚,即通过指令在前端添加了额外的uop。与上面讨论的失速相比,这些规则略有不同,适用于范围更窄的情况。特别地,所谓的标志合并uop只有当一个标志消耗指令从多个标志中读取并且这些标志上次由不同的指令设置时才被添加。这意味着,例如,检查单个标志的指令永远不会导致发出合并uop。

从Skylake开始(可能从Broadwell开始),我没有发现任何合并UOPS的证据。相反,uop格式被扩展为最多接受3个输入,这意味着单独重命名的进位标志和重命名的SPAZO组标志都可以用作大多数指令的输入。例外情况包括cmovbe这样的指令,它有两个寄存器输入,其条件be要求同时使用C标志和一个或多个SPAZO标志。然而,大多数条件移动只使用C和SPAZO标志中的一个或另一个,并使用一个UOP。

这里有一些例子。我们讨论了“[部分标志]停滞”和“合并uop”,但如上所述,这两个中最多只有一个适用于任何给定的体系结构,因此类似“以下导致一个停滞和一个合并uop被发出”的内容应该被理解为“以下导致一个停滞[在那些具有部分标志停滞的旧体系结构上]或一个合并uop[在那些使用合并uop的新体系结构上]”。

以下示例将导致在Sandy Bridge和Ivy Bridge上发射失速和合并uop,但在Skylake上不发射:

add rbx, 5   ; sets CF, ZF, others
inc rax      ; sets ZF, but not CF
ja  label    ; reads CF and ZF

ja指令读取cfzf,这两个代码分别是addinc指令最后设置的,因此插入一个合并uop以统一单独设置的标志,供ja使用。在停顿的体系结构上,由于jacf读取而导致停顿,而该cf不是由最近的标志设置指令设置的。

add rbx, 5   ; sets CF, ZF, others
inc rax      ; sets ZF, but not CF
jc  label    ; reads CF

这会导致停顿,因为在前面的示例中,读取cf,而上一个标志设置指令(这里是inc)没有对其进行设置。在这种情况下,可以通过简单地交换incadd的顺序来避免停顿,因为它们是独立的,然后jc将只读取最近的标志设置操作。不需要合并uop,因为读取的标志(只有cf)都来自同一个add指令。

注意:这个案例正在辩论中(见评论)--但我不能测试它,因为我没有在我的Skylake上找到任何合并操作的证据。

add rbx, 5   ; sets CF, ZF, others
inc rax      ; sets ZF, but not CF
jnz  label   ; reads ZF

这里不需要延迟或合并uop,尽管最后一条指令(inc)只设置了一些标志,因为消费的JNZ只读取inc设置的标志(子集),而不读取其他标志。因此,这种常见的循环习惯用法(通常使用dec而不是inc)本身并不会导致问题。

下面是另一个不会导致任何停顿或合并UOP的示例:

inc rax      ; sets ZF, but not CF
add rbx, 5   ; sets CF, ZF, others
ja  label    ; reads CF and ZF

这里,ja同时读取cfzf,并且存在一个inc,它不设置zf(即,部分标志写入指令),但是没有问题,因为add位于inc之后,并写入所有相关标志。

移位指令sarshrshl在它们的变量和固定计数形式下的行为与上面描述的不同(通常更差),并且这在不同的体系结构中有相当大的差异。这可能是由于它们奇怪且不一致的标记处理1。例如,在许多体系结构上,当读取计数不是1的移位指令后的任何标志时,会出现部分标志停滞。即使在最新的架构上,由于标记处理,可变移位也有3个uops的显著成本(但没有更多的“停滞”)。

我不打算在这里包括所有血淋淋的细节,但如果你想要所有的细节,我建议在Agner的microarch doc中寻找shift这个词。

一些旋转指令也有有趣的标志相关行为,在某些情况下类似于移位。

 类似资料:
  • 本文向大家介绍什么是偏差和方差?相关面试题,主要包含被问及什么是偏差和方差?时的应答技巧和注意事项,需要的朋友参考一下 泛化误差可以分解为偏差的平方加上方差加上噪声。 偏差度量了学习算法的期望预测和真实结果的偏离程度,刻画了学习算法本身的拟合能力 方差度量了同样大小的训练集的变动所导致的学习性能的变化,刻画了数据扰动所造成的影响 噪声表达了当前任务上任何学习算法所能达到的期望泛化误差下界,刻画了问

  • 阅读C 11标准,我无法完全理解以下陈述的含义。榜样是非常受欢迎的。 两组类型用于确定偏序。对于涉及的每个模板,都有原始函数类型和转换后的函数类型。[注:转换类型的创建在14.5.6.2.-结束注]演绎过程使用转换类型作为参数模板,另一个模板的原始类型作为参数模板。对于偏序比较中涉及的每种类型,此过程执行两次:一次使用转换后的模板-1作为参数模板,模板-2作为参数模板,再次使用转换后的模板-2作为

  • 问题内容: 我看到了很多Java代码,其中android更愿意让开发人员使用静态内部类。特别是对于自定义ListAdapters中的ViewHolder Pattern之 类的模式。 我不确定静态类和非静态类之间的区别。我已经读过它,但是在考虑性能或内存占用时似乎没有任何意义。 问题答案: 不只是Android开发人员… 非静态内部类始终保留对封闭对象的隐式引用。如果您不需要该参考,则只需花费成本

  • 问题内容: 什么是selenium? 当您打开Selenium的官方页面时,您首先读到的是“什么是Selenium?”中的“ Selenium automates browser”。部分。“selenium的哪个部分适合我?”部分 下面提供了Selenium WebDriver和Selenium IDE之间的选择。由此,我推断出Selenium是一组工具,并且该集合包括IDE,WebDriver

  • 硒是什么? 当你打开Selenium的官方页面,首先看到的是“什么是Selenium”中的“Selenium自动浏览器”。节。“硒的哪一部分对我合适?”下面提供了Selenium WebDriver和Selenium IDE之间的选择。由此,我推断Selenium是一个工具集合,该集合包括IDE、WebDriver API(语言绑定)、网格、Selenium独立服务器、浏览器驱动程序。一个人必须下

  • 本文向大家介绍为什么说朴素贝叶斯是高偏差低方差?相关面试题,主要包含被问及为什么说朴素贝叶斯是高偏差低方差?时的应答技巧和注意事项,需要的朋友参考一下 它简单假设了各个特征之间是无关的,是一个被严重简化了的模型,所以,对于这样一个简单模型,大部分场合都会bias部分大于variance部分,也就是高偏差低方差