相关疑难解决方法(0)

如何减轻英特尔 jcc 勘误对 gcc 的影响?

如果我有一个受Intel jcc erratum约束的芯片,我如何在 gcc 中启用缓解(它调整分支位置以避免有问题的对齐),以及哪些 gcc 版本支持它?

x86 gcc intel compiler-flags

9
推荐指数
1
解决办法
139
查看次数

32 字节对齐例程不适合 uops 缓存

KbL i7-8550U

我正在研究 uops-cache 的行为并遇到了关于它的误解。

如英特尔优化手册2.5.2.2(我的)中所述:

解码的 ICache 由 32 组组成。每组包含八种方式。 每路最多可容纳六个微操作。

——

Way 中的所有微操作表示在代码中静态连续的指令,并且它们的 EIP 位于相同的对齐 32 字节区域内。

——

最多三种方式可以专用于相同的 32 字节对齐块,从而允许在原始 IA 程序的每个 32 字节区域中缓存总共 18 个微操作。

——

无条件分支是 Way 中的最后一个微操作。


情况1:

考虑以下例程:

uop.h

void inhibit_uops_cache(size_t);
Run Code Online (Sandbox Code Playgroud)

uop.S

align 32
inhibit_uops_cache:
    mov edx, esi
    mov edx, esi
    mov edx, esi
    mov edx, esi
    mov edx, esi
    mov edx, esi
    jmp decrement_jmp_tgt
decrement_jmp_tgt:
    dec rdi
    ja inhibit_uops_cache ;ja is intentional to avoid Macro-fusion
    ret
Run Code Online (Sandbox Code Playgroud)

为了确保例程的代码实际上是 32 字节对齐的,这里是 asm …

performance x86 assembly intel cpu-architecture

7
推荐指数
1
解决办法
483
查看次数

当跳转在 32 字节上没有完全对齐时,使用 MITE(传统管道)代替 DSB(uop 缓存)

这个问题曾经是这个(现已更新)问题的一部分,但它似乎应该是另一个问题,因为它无助于获得另一个问题的答案。


我的出发点是一个循环进行 3 个独立的添加:

for (unsigned long i = 0; i < 2000000000; i++) {
    asm volatile("" : "+r" (a), "+r" (b), "+r" (c), "+r" (d)); // prevents C compiler from optimizing out adds
    a = a + d;
    b = b + d;
    c = c + d;
}
Run Code Online (Sandbox Code Playgroud)

当这个循环没有展开时,它在 1 个周期内执行(这是预期的:它包含 4 条指令:3 个加法和宏融合增量/跳转;所有这些都可以在端口 0 上在一个周期内执行, 1、5 和 6)。展开此循环时,性能令人惊讶,并且往往比未展开的版本慢 25%,这可能是由于 uops 调度,如上一个问题的评论中所建议的。

在这个问题中,我不是在问性能,而是在问为什么在某些情况下,uop 来自 MITE(传统管道),而在其他情况下,来自 DSB(uop 缓存)。(请注意,我使用的是禁用 LSD(循环流检测器)的 Skylake)

实验上,当跳转在 32 字节上没有完全对齐时,uop 是从 MITE …

performance x86 assembly intel

6
推荐指数
1
解决办法
205
查看次数

英特尔 JCC 勘误表 - 真的应该单独对待 JCC 吗?

英特尔推送微码更新以修复名为“跳转条件代码 (JCC) 勘误表”的错误。由于在某些条件下禁用将代码放入 ICache,更新微码导致某些操作效率低下。

已发布的文档,标题为跳转条件代码勘误的缓解措施不仅列出了JCC,还列出了:无条件跳转、条件跳转、宏融合条件跳转、调用和返回。

MSVC 开关/QIntel-jcc-erratum文档提到:

在 /QIntel-jcc-erratum 下,编译器检测跨越或结束于 32 字节边界的跳转和宏融合跳转指令。

问题是:

  • 是否有理由将 JCC 与其他跳转分开处理?
  • 是否有理由将宏融合 JCC 与其他 JCC 分开处理?

x86 assembly intel cpu-architecture micro-architecture

3
推荐指数
1
解决办法
363
查看次数

为什么在 Python 3.12 中执行简单的 for 循环比在 Python 3.11 中花费更长的时间?

Python 3.12 两天前发布,包含多项新功能和改进。它声称它比以往任何时候都快,所以我决定尝试一下。我用新版本运行了一些脚本,但速度比以前慢。我尝试了各种方法,每次都简化我的代码,试图找出导致其运行缓慢的瓶颈。然而,到目前为止我还没有成功。最后,我决定测试一个简单的 for 循环,如下所示:

import time

def calc():
    for i in range(100_000_000):
        x = i * 2

t = time.time()
calc()
print(time.time() - t)
Run Code Online (Sandbox Code Playgroud)

在我的机器上,Python 3.11.5 上需要 4.7 秒,Python 3.12.0 上需要 5.7 秒。在其他机器上尝试也得到了类似的结果。

那么为什么在最新版本的Python中它会变慢呢?

python performance

3
推荐指数
1
解决办法
2107
查看次数