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

英特尔JCC勘误-用于缓解的前缀的效果是什么?

常雅珺
2023-03-14

英特尔建议使用指令前缀来减轻JCC勘误的性能后果。

如果使用QIntel jcc勘误表编译MSVC,则遵循建议,并插入前缀指令,如下所示:

3E 3E 3E 3E 3E 3E 3E 3E 3E 48 8B C8   mov rcx,rax ; with redundant 3E prefixes

他们说当前缀不可能时,MSVC会求助于NOP。

Clang对此有-mbranches-within-32B-bounders选项,如果需要,它更喜欢多字节(https://godbolt.org/z/399nc5Msq注意:xchg ax,ax

3E前缀的后果是什么,具体来说:

  • 为什么Intel推荐这一点,而不是多字节NOP
  • 对未受影响的CPU有什么后果
  • 据报道,AMD上的QIntel jcc勘误表程序运行速度更快,有什么可能的解释

共有1个答案

方和豫
2023-03-14

NOP是一条单独的指令,必须单独解码并通过管道。最好是在指令中添加前缀以实现所需的对齐,而不是插入NOP,正如在现代x86上可以使用哪些方法有效地扩展指令长度中所讨论的那样?(但只有在不会导致某些无法处理大量前缀的CPU出现大暂停的情况下)。

也许Intel认为工具链在这种情况下这样做是值得的,因为这实际上是内部循环,而不仅仅是内部循环外的NOP。(在前面的一条指令上加前缀相对简单。)

我现在有一些数据点。AMD FX 8300上QIntel jcc勘误表的基准测试结果不好。

对于一个特定的基准测试,速度会下降一个小数量级,而英特尔Skylake对同一基准测试的好处约为20%。这与Peter的评论一致:

我查看了Agner Fog的Microach指南,AMD Zen对单个指令上的任何前缀都没有问题,就像自Core2以来的主流Intel一样。AMD推土机系列对于3个以上前缀的解码指令有“非常大”的惩罚,如4-7个前缀有14-15个周期

虽然仍然有一些APU台式机和笔记本电脑,但如果编译器在热内部循环(包括REX或66h等现有前缀)中的一条指令上添加了4个或更多前缀,那么认为推土机系列已经过时而不太关心它,这在某种程度上是有道理的,但它们肯定会在循环中显示出很大的倒退。比SKL上MITE legacy解码的3%差得多。

虽然推土机家族确实过时了,但我认为我承受不起这么大的影响。我还担心其他CPU会以同样的方式被额外的前缀阻塞。因此,我的结论是,不要将QIntel jcc勘误表用于一般目标软件。除非在特定的翻译单元中启用它,并对其进行动态调度,否则大多数情况下这会带来太多的麻烦。

在MSVC上可能安全的一件事是停止使用Os标志。发现操作系统标记至少:

  • 避免跳转表,支持条件跳转

尝试以下示例(https://godbolt.org/z/jvezPd9jM):

void loop(int i, char a[], char b[])
{
    char* stop = a + i;
    while (a != stop){
        *b++ = *a++;
    }
}

void jump_table(int i, char a[], char b[])
{
    switch (i)
    {
                            case 7: 
            a[6] = b[6];    case 6: 
            a[5] = b[5];    case 5: 
            a[4] = b[4];    case 4: 
            a[3] = b[3];    case 3: 
            a[2] = b[2];    case 2: 
            a[1] = b[1];    case 1: 
            a[0] = b[1];    case 0:  break;
            default: __assume(false);
    }
}

这会导致更频繁地遇到JCC perf问题(避免跳转表会产生一系列JCC,避免对齐会使小循环少于16b有时也会触及边界)

 类似资料:
  • Intel推动微码更新以修复名为“跳转条件码(JCC)勘误表”的错误。由于在某些情况下禁用将代码放入ICache,更新微码导致某些操作效率低下。 标题为“跳转条件代码勘误表的缓解措施”的已发布文档不仅列出了JCC,还列出了:无条件跳转、条件跳转、宏融合条件跳转、调用和返回。 MSVC交换机文档中提到: 在/QIntel jcc勘误表下,编译器检测跨越或终止于32字节边界的跳转指令和宏融合跳转指令。

  • 如果我有一个受“英特尔jcc勘误表”约束的芯片,我如何在gcc中启用缓解措施(调整分支位置以避免出现问题的对齐),以及哪个gcc版本支持它?

  • 问题内容: 从我读到的内容来看,它用于修复CPU中的错误,而无需修改BIOS。根据我对汇编的基本知识,我知道汇编指令在内部由CPU分解为微代码,并相应地执行。但是intel以某种方式可以在系统启动和运行时进行一些更新。 有人有更多信息吗?是否有关于微码可以做什么以及如何使用的文档? 编辑:我读过维基百科的文章:没弄清楚我怎么能自己写一些,以及它有什么用。 问题答案: 在较早的时期,微代码在CPU中

  • 问题内容: 我知道,如果要确保某些CSS3功能在任何地方都可以使用,我们需要使用W3C推荐的前缀版本,例如: 我知道这些前缀用于实验功能,但为什么有必要?他们为什么不在原始W3C上测试它们?每个CSS3功能是否都为每个浏览器都具有或具有前缀,或者如果他们认为应该的话,他们只是创建带前缀的版本? 问题答案: 供应商前缀的最初目的是使供应商能够添加自己的非标准功能以供其CSS实现使用。但是,它们中的大

  • 今天我想:好吧,即使人们对NIST SP 800-90A的RDRAND实现有很大的怀疑,它仍然是伪随机数生成器(PRNG)的硬件实现,对于非敏感应用程序来说必须足够好。所以我想在我的比赛中使用它,而不是Mersenne Twister。 因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间: 和 通过运行这两个,我得到: 所以,Mersenne Twister在我的CPU上比RD

  • 本人背景算法工程师,cv方向论文两篇,nlp实习经历。 一轮 25min 自我介绍 询问项目论文 问题:resnet架构、c++程序执行过程 反问 二轮 40min 自我介绍 询问项目论文(论文很细致,结构、损失、数据集、实验结果、创新点) 问题:Transformer架构、核心公式以及采用什么的正则化、BN和LN的区别。其实大部分是根据论文内容发散 反问 三轮HR面 25min 没有自我介绍 问