gpt4 book ai didi

performance - 不同内核版本性能回归原因分析

转载 作者:行者123 更新时间:2023-12-03 13:36:47 24 4
gpt4 key购买 nike

我在 x86_64 系统上遇到了从 Linux 内核 3.11 到 3.12 的奇怪性能回归。
正在运行Mark Stock's Radiance benchmark在 Fedora 20 上,3.12 明显较慢。没有其他任何改变 - 相同的二进制文件,相同的 glibc - 我只是启动了不同的内核版本,并且性能发生了变化。
定时程序 rpict 是 100% CPU 绑定(bind)的用户级代码。

在我将此报告为错误之前,我想找出导致此行为的原因。我对 Linux 内核了解不多,从 3.11 到 3.12 的更改日志也没有给我任何线索。

我在两个系统上观察到这一点,一个 Intel Haswell (i7-4771) 和一个 AMD Richland (A8-6600K)。
在 Haswell 系统上,用户时间从 3.11 的 895 秒变为 3.12 的 962 秒。在里奇兰,从 1764 年到 1844 年。这些时间可以在几秒钟内重复。

我用 perf 做了一些分析,发现 IPC 的下降与减速的比例相同。在 Haswell 系统上,这似乎是由于更多的错过分支造成的,但为什么预测率会下降呢? Radiance 确实使用了随机数生成器——“更好”的随机性会导致丢失的分支吗?但除了 OMAP4 支持之外,RNG 在 3.12 中似乎不需要更改。

在 AMD 系统上,perf 只是指向更多的空闲后端周期,但原因尚不清楚。

哈斯韦尔系统:

3.11.10  895s user, 3.74% branch-misses, 1.65 insns per cycle
3.12.6 962s user, 4.22% branch-misses, 1.52 insns per cycle

里奇兰系统:
3.11.10  1764s user, 8.23% branch-misses, 0.75 insns per cycle
3.12.6 1844s user, 8.26% branch-misses, 0.72 insns per cycle

我还查看了两个内核的 dmesg 输出的差异,但没有看到任何可能导致 CPU 密集型程序如此缓慢的东西。

我尝试将 cpufreq 调节器从默认的按需切换到性能,但这没有任何效果。

可执行文件是使用 gcc 4.7.3 编译的,但没有使用 AVX 指令。 libm 似乎仍然使用一些 AVX(例如 __ieee754_pow_fma4 ),但这些函数仅占总执行时间的 0.3%。

附加信息:
  • Diff of kernel configs
  • diff of the dmesg outputs在 Haswell 系统上。
  • diff of /proc/pid/maps - 3.11 只映射一个堆区域; 3.12 手。
  • perf stat output来自 A8-6600K 系统
  • perf stats w/ TLB misses dTLB 统计数据看起来非常不同!
  • /usr/bin/time -v output来自 A8-6600K 系统

  • 有什么想法(除了将内核更改一分为二)?

    最佳答案

    让我们检查一下您的 perf stat输出:http://www.chr-breitkopf.de/tmp/perf-stat.A8.txt

    内核 3.11.10

        1805057.522096 task-clock                #    0.999 CPUs utilized          
    183,822 context-switches # 0.102 K/sec
    109 cpu-migrations # 0.000 K/sec
    40,451 page-faults # 0.022 K/sec
    7,523,630,814,458 cycles # 4.168 GHz [83.31%]
    628,027,409,355 stalled-cycles-frontend # 8.35% frontend cycles idle [83.34%]
    2,688,621,128,444 stalled-cycles-backend # 35.74% backend cycles idle [33.35%]
    5,607,337,995,118 instructions # 0.75 insns per cycle
    # 0.48 stalled cycles per insn [50.01%]
    825,679,208,404 branches # 457.425 M/sec [66.67%]
    67,984,693,354 branch-misses # 8.23% of all branches [83.33%]

    1806.804220050 seconds time elapsed

    内核 3.12.6
        1875709.455321 task-clock                #    0.999 CPUs utilized          
    192,425 context-switches # 0.103 K/sec
    133 cpu-migrations # 0.000 K/sec
    40,356 page-faults # 0.022 K/sec
    7,822,017,368,073 cycles # 4.170 GHz [83.31%]
    634,535,174,769 stalled-cycles-frontend # 8.11% frontend cycles idle [83.34%]
    2,949,638,742,734 stalled-cycles-backend # 37.71% backend cycles idle [33.35%]
    5,607,926,276,713 instructions # 0.72 insns per cycle
    # 0.53 stalled cycles per insn [50.01%]
    825,760,510,232 branches # 440.239 M/sec [66.67%]
    68,205,868,246 branch-misses # 8.26% of all branches [83.33%]

    1877.263511002 seconds time elapsed

    3.12.6 在“周期”字段中还有近 300 个 Gcycle;只有 6,5 个 Gcycles 是前端的停顿,而 261 个 Gcycles 是在后端停顿的。您只有 0,2 G 的额外分支未命中(每个花费大约 20 个周期 - 每个 optim.manual 第 597 页;所以 4Gcycles),所以我认为您的性能问题与内存子系统问题有关(更现实的后端事件,它可以受内核影响)。页面错误差异和迁移计数很低,我认为它们不会直接减慢测试速度(但迁移可能会将程序移动到更糟糕的地方)。

    您应该深入了解 perf计数器来查找问题的确切类型(如果您的测试运行时间较短,这将更容易)。英特尔手册 http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf会帮助你。查看第 587 页 (B.3.2) 了解整体事件层次结构(FE 和 BE 停顿也在这里),B.3.2.1-B.3.2.3 了解有关后端停顿以及如何开始挖掘的信息(检查缓存事件等) ) 及以下。

    内核如何影响内存子系统?它可以设置不同的虚拟到物理的映射(几乎不是你的情况),或者它可以将过程移离数据更远。您没有 NUMA 机器,但 Haswell 不是确切的 UMA - 有一个环形总线,一些内核更接近内存 Controller 或共享 LLC(最后一级缓存)的某些部分。您可以使用 taskset 测试您的程序实用程序,将其绑定(bind)到某个核心 - 内核不会将其移动到其他核心。

    更新:在检查了来自 A8 的新性能统计信息后,我们发现 3.12.6 有更多的 DLTB 未命中。随着/proc/pid/maps 的变化(很多短 [heap] 部分而不是单个 [heap] ,仍然没有确切的信息为什么),我认为透明大页(THP;2M大页)可能会有所不同相同数量的内存和更少的 tlb 未命中所需的 TLB 条目),例如在 3.12 中,由于堆段短,它无法应用。

    您可以查看您的 /proc/PID/smaps对于 AnonHugePages/proc/vmstat用于 thp* 值以查看 thp 结果。此处记录了值 kernel.org/doc/Documentation/vm/transhuge.txt

    @osgx You found the cause! After echo never > /sys/kernel/mm/transparent_hugepage/enabled, 3.11.10 takes as long as 3.12.6!



    好消息!

    Additional info on how to disable the randomization, and on where to report this as a bug (a 7% performance regression is quite severe) would be appreciated



    我错了,这种多堆部分效果不是 brk 随机化(它只改变堆的开头)。这是 do_brk 中的 VMA 合并失败;不知道为什么,但是在 mm 中可以看到 VM_SOFTDIRTY 的一些变化。 3.11.10 - 3.12.6 之间。

    UPDATE2:未合并 VMA 的可能原因:

    http://lxr.missinglinkelectronics.com/linux+v3.11/mm/mmap.c#L2580 3.11 中的 do_brk

    http://lxr.missinglinkelectronics.com/linux+v3.11/mm/mmap.c#L2577 3.12 中的 do_brk

    3.12 刚刚在 do_brk 末尾添加
    2663        vma->vm_flags |= VM_SOFTDIRTY;
    2664 return addr;

    上面我们有
    2635        /* Can we just expand an old private anonymous mapping? */
    2636 vma = vma_merge(mm, prev, addr, addr + len, flags,
    2637 NULL, NULL, pgoff, NULL);

    和里面 vma_merge有 vm_flags 测试

    http://lxr.missinglinkelectronics.com/linux+v3.11/mm/mmap.c#L994 3.11

    http://lxr.missinglinkelectronics.com/linux+v3.12/mm/mmap.c#L994 3.12
    1004        /*
    1005 * We later require that vma->vm_flags == vm_flags,
    1006 * so this tests vma->vm_flags & VM_SPECIAL, too.
    1007 */

    vma_merge --> can_vma_merge_before --> is_mergeable_vma ...
     898        if (vma->vm_flags ^ vm_flags)
    899 return 0;

    但是在检查时,新的 vma 没有被标记为 VM_SOFTDIRTY,而旧的 vma 已经被标记了。

    关于performance - 不同内核版本性能回归原因分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20997809/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com