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

为什么打破LZCNT的“输出依赖”很重要?

鲜于宏义
2023-03-14

在基准测试时,我测量到的吞吐量比我计算的低得多,我将其缩小到LZCNT指令(它也发生在TZCNT中),如以下基准测试所示:

  xor ecx, ecx
_benchloop:
  lzcnt eax, edx
  add ecx, 1
  jnz _benchloop

和:

  xor ecx, ecx
_benchloop:
  xor eax, eax  ; this shouldn't help, but it does
  lzcnt eax, edx
  add ecx, 1
  jnz _benchloop

我是在4770K上运行的,所以LZCNT和TZCNT不是作为BSR/BSF执行的。

这是怎么回事?

共有1个答案

羊刚捷
2023-03-14

这只是Intel Haswell CPU和之前几个1CPU的微架构的一个限制。在Skylake-S(客户端)中,已修复了TZCNTLZCNT的问题,但在Cannon Lake中修复之前,POPCNT的问题仍然存在。

在这些微体系结构上,tzcntlzcntpopcnt的目标操作数被视为输入依赖项,尽管语义上不是。现在我怀疑这是一个真正的“bug”:如果它只是一个无意的行为/疏忽,我想它应该已经在几个新的微架构中被修复了。

最有可能的是基于以下两个因素之一或两者的设计折衷:

>

  • POPCNTLZCNTTZCNT的硬件可能都与现有的BSFBSR指令共享。现在,BSFBSR对于全位零输入的特殊情况确实依赖于先前的目的地值2,因为Intel芯片在这种情况下不修改目的地。因此,组合硬件的最简单设计完全有可能导致在同一单元上执行的其他类似指令继承相同的依赖关系。

    绝大多数x86双操作数ALU指令都依赖于目标操作数,因为它也被用作源。受影响的三条指令有些独特,因为它们是一元运算符,但与现有的一元运算符(如notneg)不同,它们具有不同的源和目标操作数,这使得它们在表面上类似于大多数2输入指令。也许重命名器/调度器电路没有区分这些一元带两个寄存器操作数的特殊情况,而绝大多数简单共享的源/目的地2输入指令没有这种依赖关系。

    事实上,对于popcnt,Intel已经发布了各种勘误表,涵盖了虚假依赖项问题,如Haswell Desktop的HSD146和Skylake的SKL029,内容如下:

    POPCNT指令执行时间可能比预期的长

    使用32位或64位操作数的问题POPCNT指令执行可能会被延迟,直到先前的非依赖指令已经执行。

    解决方案无标识

    我总是发现这个勘误表不寻常,因为它并不能真正识别出任何类型的功能缺陷或不符合规范,而实际上所有其他勘误表都是如此。Intel并没有真正为OoO执行引擎记录一个具体的性能模型,而且在过去的几年里,还有很多其他性能“错误”出现了又消失了(其中许多错误的影响比这个很小的问题大得多),这些错误没有在勘误表中记录下来。不过,这也许提供了一些证据,表明它可以被认为是一个bug。奇怪的是,勘误表从未扩展到包括tzcntlzcnt,它们在引入时有相同的问题。

    1WellTZCNTLZCNT只在Haswell中出现,但在Nehalem中引入的POPCNT也存在这个问题--但错误依赖问题可能只在Sandy Bridge或更高版本中存在。

    2实际上,虽然在ISA文档中没有记录,因为全零输入的结果在Intel手册中没有定义。然而,在这种情况下,大多数或所有Intel芯片实现的行为都是保持目标寄存器不变。

  •  类似资料:
    • 问题内容: 我认为Maven依赖关系的顺序之前无关紧要,并认为这是它的一个优点。这是我以前的依赖项: 它运作良好,今天我要把对弹簧的依赖移到最底层,以便与那些球衣相关的东西可以在一起。但是后来我再也无法正常工作了,我的码头抱怨道: 那真的很令人困惑,所以我是否需要考虑依赖顺序?我怎么知道正确的顺序? 问题答案: 依赖关系的顺序确实很重要,因为从2.0.9版开始,Maven如何解决传递依赖关系。文档

    • 我的理解是 x == 0 首先运行。但是 x 在计算时仍然是 -1 (y = y / x) == 0?否则它将除以零。我以为输出将是 -5,但日食说 5。我快疯了。

    • 为了尽快获得一个可以高效使用的工作软件系统,不仅需要为开发做计划,还需要为文档,部署,市场做计划。在一个商业工程里,这还需要销售和金融计划。没有对开发时间的预测能力,是不可能高效预测以上这些东西的。 好的估计提供了预测能力。管理者喜欢,而且应该这么做。事实是这不可能,不论是理论上还是实践上,准确预测开发软件所消耗的时间总是被管理者所忽视。我们总是被要求做那些不可能的事情,而且我们必须诚实地面对它。

    • 考虑下面这个只获得IP和端口号的类: 并且将是控制器类 现在<code>服务器控制器<code>处于一个while(true)循环中,直到用户输入IP和端口。 如何避免这种依赖关系(避免while循环)?

    • 问题内容: 我最近找到了一个示例代码: 该方法将打开一个用户界面窗口。然后,我尝试将代码修剪如下: 两种版本均能正常工作。有什么区别? 问题答案: 任何一种代码都能在99%的时间内工作。 但是,Swing的设计使得对Swing组件的所有更新都应在事件分发线程(EDT)上完成。阅读有关并发的Swing教程以获取更多信息。 问题是它有1%的时间可能无法正常工作。您不想浪费时间尝试调试随机问题。

    • 本文向大家介绍为什么Kafka技术很重要?相关面试题,主要包含被问及为什么Kafka技术很重要?时的应答技巧和注意事项,需要的朋友参考一下 答:Kafka有一些优点,因此使用起来很重要: 高吞吐量:我们在Kafka中不需要任何大型硬件,因为它能够处理高速和大容量数据。此外,它还可以支持每秒数千条消息的消息吞吐量。 低延迟:Kafka可以轻松处理这些消息,具有毫秒级的极低延迟,这是大多数新用例所要求