gpt4 book ai didi

performance - 英特尔 Broadwell 处理器出现明显的 FMA 性能异常

转载 作者:行者123 更新时间:2023-12-03 08:04:22 26 4
gpt4 key购买 nike

  • 代码1:
    vzeroall
    mov rcx, 1000000
    startLabel1:
    vfmadd231ps ymm0, ymm0, ymm0
    vfmadd231ps ymm1, ymm1, ymm1
    vfmadd231ps ymm2, ymm2, ymm2
    vfmadd231ps ymm3, ymm3, ymm3
    vfmadd231ps ymm4, ymm4, ymm4
    vfmadd231ps ymm5, ymm5, ymm5
    vfmadd231ps ymm6, ymm6, ymm6
    vfmadd231ps ymm7, ymm7, ymm7
    vfmadd231ps ymm8, ymm8, ymm8
    vfmadd231ps ymm9, ymm9, ymm9
    vpaddd ymm10, ymm10, ymm10
    vpaddd ymm11, ymm11, ymm11
    vpaddd ymm12, ymm12, ymm12
    vpaddd ymm13, ymm13, ymm13
    vpaddd ymm14, ymm14, ymm14
    dec rcx
    jnz startLabel1
  • 代码2:
    vzeroall
    mov rcx, 1000000
    startLabel2:
    vmulps ymm0, ymm0, ymm0
    vmulps ymm1, ymm1, ymm1
    vmulps ymm2, ymm2, ymm2
    vmulps ymm3, ymm3, ymm3
    vmulps ymm4, ymm4, ymm4
    vmulps ymm5, ymm5, ymm5
    vmulps ymm6, ymm6, ymm6
    vmulps ymm7, ymm7, ymm7
    vmulps ymm8, ymm8, ymm8
    vmulps ymm9, ymm9, ymm9
    vpaddd ymm10, ymm10, ymm10
    vpaddd ymm11, ymm11, ymm11
    vpaddd ymm12, ymm12, ymm12
    vpaddd ymm13, ymm13, ymm13
    vpaddd ymm14, ymm14, ymm14
    dec rcx
    jnz startLabel2
  • Code3(与 Code2 相同,但具有长 VEX 前缀):
    vzeroall
    mov rcx, 1000000
    startLabel3:
    byte 0c4h, 0c1h, 07ch, 059h, 0c0h ;long VEX form vmulps ymm0, ymm0, ymm0
    byte 0c4h, 0c1h, 074h, 059h, 0c9h ;long VEX form vmulps ymm1, ymm1, ymm1
    byte 0c4h, 0c1h, 06ch, 059h, 0d2h ;long VEX form vmulps ymm2, ymm2, ymm2
    byte 0c4h, 0c1h, 06ch, 059h, 0dbh ;long VEX form vmulps ymm3, ymm3, ymm3
    byte 0c4h, 0c1h, 05ch, 059h, 0e4h ;long VEX form vmulps ymm4, ymm4, ymm4
    byte 0c4h, 0c1h, 054h, 059h, 0edh ;long VEX form vmulps ymm5, ymm5, ymm5
    byte 0c4h, 0c1h, 04ch, 059h, 0f6h ;long VEX form vmulps ymm6, ymm6, ymm6
    byte 0c4h, 0c1h, 044h, 059h, 0ffh ;long VEX form vmulps ymm7, ymm7, ymm7
    vmulps ymm8, ymm8, ymm8
    vmulps ymm9, ymm9, ymm9
    vpaddd ymm10, ymm10, ymm10
    vpaddd ymm11, ymm11, ymm11
    vpaddd ymm12, ymm12, ymm12
    vpaddd ymm13, ymm13, ymm13
    vpaddd ymm14, ymm14, ymm14
    dec rcx
    jnz startLabel3
  • Code4(与 Code1 相同,但带有 xmm 寄存器):
    vzeroall
    mov rcx, 1000000
    startLabel4:
    vfmadd231ps xmm0, xmm0, xmm0
    vfmadd231ps xmm1, xmm1, xmm1
    vfmadd231ps xmm2, xmm2, xmm2
    vfmadd231ps xmm3, xmm3, xmm3
    vfmadd231ps xmm4, xmm4, xmm4
    vfmadd231ps xmm5, xmm5, xmm5
    vfmadd231ps xmm6, xmm6, xmm6
    vfmadd231ps xmm7, xmm7, xmm7
    vfmadd231ps xmm8, xmm8, xmm8
    vfmadd231ps xmm9, xmm9, xmm9
    vpaddd xmm10, xmm10, xmm10
    vpaddd xmm11, xmm11, xmm11
    vpaddd xmm12, xmm12, xmm12
    vpaddd xmm13, xmm13, xmm13
    vpaddd xmm14, xmm14, xmm14
    dec rcx
    jnz startLabel4
  • Code5(与 Code1 相同,但具有非归零 vpsubd`s):
    vzeroall
    mov rcx, 1000000
    startLabel5:
    vfmadd231ps ymm0, ymm0, ymm0
    vfmadd231ps ymm1, ymm1, ymm1
    vfmadd231ps ymm2, ymm2, ymm2
    vfmadd231ps ymm3, ymm3, ymm3
    vfmadd231ps ymm4, ymm4, ymm4
    vfmadd231ps ymm5, ymm5, ymm5
    vfmadd231ps ymm6, ymm6, ymm6
    vfmadd231ps ymm7, ymm7, ymm7
    vfmadd231ps ymm8, ymm8, ymm8
    vfmadd231ps ymm9, ymm9, ymm9
    vpsubd ymm10, ymm10, ymm11
    vpsubd ymm11, ymm11, ymm12
    vpsubd ymm12, ymm12, ymm13
    vpsubd ymm13, ymm13, ymm14
    vpsubd ymm14, ymm14, ymm10
    dec rcx
    jnz startLabel5
  • Code6b:(已修订,仅用于 vpaddds 的内存操作数)
    vzeroall
    mov rcx, 1000000
    startLabel6:
    vfmadd231ps ymm0, ymm0, ymm0
    vfmadd231ps ymm1, ymm1, ymm1
    vfmadd231ps ymm2, ymm2, ymm2
    vfmadd231ps ymm3, ymm3, ymm3
    vfmadd231ps ymm4, ymm4, ymm4
    vfmadd231ps ymm5, ymm5, ymm5
    vfmadd231ps ymm6, ymm6, ymm6
    vfmadd231ps ymm7, ymm7, ymm7
    vfmadd231ps ymm8, ymm8, ymm8
    vfmadd231ps ymm9, ymm9, ymm9
    vpaddd ymm10, ymm10, [mem]
    vpaddd ymm11, ymm11, [mem]
    vpaddd ymm12, ymm12, [mem]
    vpaddd ymm13, ymm13, [mem]
    vpaddd ymm14, ymm14, [mem]
    dec rcx
    jnz startLabel6
  • Code7:(与 Code1 相同,但 vpaddds 使用 ymm15)
    vzeroall
    mov rcx, 1000000
    startLabel7:
    vfmadd231ps ymm0, ymm0, ymm0
    vfmadd231ps ymm1, ymm1, ymm1
    vfmadd231ps ymm2, ymm2, ymm2
    vfmadd231ps ymm3, ymm3, ymm3
    vfmadd231ps ymm4, ymm4, ymm4
    vfmadd231ps ymm5, ymm5, ymm5
    vfmadd231ps ymm6, ymm6, ymm6
    vfmadd231ps ymm7, ymm7, ymm7
    vfmadd231ps ymm8, ymm8, ymm8
    vfmadd231ps ymm9, ymm9, ymm9
    vpaddd ymm10, ymm15, ymm15
    vpaddd ymm11, ymm15, ymm15
    vpaddd ymm12, ymm15, ymm15
    vpaddd ymm13, ymm15, ymm15
    vpaddd ymm14, ymm15, ymm15
    dec rcx
    jnz startLabel7
  • Code8:(与 Code7 相同,但使用 xmm 而不是 ymm)
    vzeroall
    mov rcx, 1000000
    startLabel8:
    vfmadd231ps xmm0, ymm0, ymm0
    vfmadd231ps xmm1, xmm1, xmm1
    vfmadd231ps xmm2, xmm2, xmm2
    vfmadd231ps xmm3, xmm3, xmm3
    vfmadd231ps xmm4, xmm4, xmm4
    vfmadd231ps xmm5, xmm5, xmm5
    vfmadd231ps xmm6, xmm6, xmm6
    vfmadd231ps xmm7, xmm7, xmm7
    vfmadd231ps xmm8, xmm8, xmm8
    vfmadd231ps xmm9, xmm9, xmm9
    vpaddd xmm10, xmm15, xmm15
    vpaddd xmm11, xmm15, xmm15
    vpaddd xmm12, xmm15, xmm15
    vpaddd xmm13, xmm15, xmm15
    vpaddd xmm14, xmm15, xmm15
    dec rcx
    jnz startLabel8

  • 在禁用 Turbo 和 C1E 的情况下测量的 TSC 时钟:
              Haswell        Broadwell                  Skylake

    CPUID 306C3, 40661 306D4, 40671 506E3

    Code1 ~5000000 ~7730000 ->~54% slower ~5500000 ->~10% slower
    Code2 ~5000000 ~5000000 ~5000000
    Code3 ~6000000 ~5000000 ~5000000
    Code4 ~5000000 ~7730000 ~5500000
    Code5 ~5000000 ~7730000 ~5500000
    Code6b ~5000000 ~8380000 ~5500000
    Code7 ~5000000 ~5000000 ~5000000
    Code8 ~5000000 ~5000000 ~5000000
  • 有人可以解释一下在 Broadwell 上 Code1 会发生什么吗?我的猜测是
    然而,Broadwell 在 Code1 案例中以某种方式用 vpaddds 污染了 Port1
    只有 Port0 和 Port1 已满,Haswell 才能使用 Port5;
  • 你有什么想法用 FMA 指令完成 Broadwell 上的 ~5000000 clk 吗?
  • 我试图重新排序。 double 和 qword 的类似行为;
  • 我使用的是 Windows 8.1 和 Win 10;

    更新:

  • 将 Code3 作为 Marat Dukhan 的想法添加了长 VEX;
  • 使用 Skylake 体验扩展了结果表;
  • 上传了一个VS2015社区+MASM示例代码here

    更新2:

  • 我尝试使用 xmm 寄存器而不是 ymm(代码 4)。在 Broadwell 上的结果相同。

    更新3:

  • 我将 Code5 添加为 Peter Cordes 的想法(将 vpaddd 替换为其他指令(vpxor、vpor、vpand、vpandn、vpsubd))。如果新指令不是归零习语(vpxor, vpsubd with same register),则在 BDW 上的结果相同。使用 Code4 和 Code5 更新的示例项目。

    更新4:

  • 我将 Code6 添加为 Stephen Canon 的想法(内存操作数)。结果是 ~8200000 时钟。
    使用 Code6 更新的示例项目;
  • 我用 AIDA64 的系统稳定性测试检查了 CPU 频率和可能的节流。频率稳定,无节流迹象;

    enter image description here
  • Intel IACA 2.1 Haswell 吞吐量分析:
    Intel(R) Architecture Code Analyzer Version - 2.1
    Analyzed File - Assembly.obj
    Binary Format - 64Bit
    Architecture - HSW
    Analysis Type - Throughput

    Throughput Analysis Report
    --------------------------
    Block Throughput: 5.10 Cycles Throughput Bottleneck: Port0, Port1, Port5

    Port Binding In Cycles Per Iteration:
    ---------------------------------------------------------------------------------------
    | Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 |
    ---------------------------------------------------------------------------------------
    | Cycles | 5.0 0.0 | 5.0 | 0.0 0.0 | 0.0 0.0 | 0.0 | 5.0 | 1.0 | 0.0 |
    ---------------------------------------------------------------------------------------

    | Num Of | Ports pressure in cycles | |
    | Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | |
    ---------------------------------------------------------------------------------
    | 1 | 1.0 | | | | | | | | CP | vfmadd231ps ymm0, ymm0, ymm0
    | 1 | | 1.0 | | | | | | | CP | vfmadd231ps ymm1, ymm1, ymm1
    | 1 | 1.0 | | | | | | | | CP | vfmadd231ps ymm2, ymm2, ymm2
    | 1 | | 1.0 | | | | | | | CP | vfmadd231ps ymm3, ymm3, ymm3
    | 1 | 1.0 | | | | | | | | CP | vfmadd231ps ymm4, ymm4, ymm4
    | 1 | | 1.0 | | | | | | | CP | vfmadd231ps ymm5, ymm5, ymm5
    | 1 | 1.0 | | | | | | | | CP | vfmadd231ps ymm6, ymm6, ymm6
    | 1 | | 1.0 | | | | | | | CP | vfmadd231ps ymm7, ymm7, ymm7
    | 1 | 1.0 | | | | | | | | CP | vfmadd231ps ymm8, ymm8, ymm8
    | 1 | | 1.0 | | | | | | | CP | vfmadd231ps ymm9, ymm9, ymm9
    | 1 | | | | | | 1.0 | | | CP | vpaddd ymm10, ymm10, ymm10
    | 1 | | | | | | 1.0 | | | CP | vpaddd ymm11, ymm11, ymm11
    | 1 | | | | | | 1.0 | | | CP | vpaddd ymm12, ymm12, ymm12
    | 1 | | | | | | 1.0 | | | CP | vpaddd ymm13, ymm13, ymm13
    | 1 | | | | | | 1.0 | | | CP | vpaddd ymm14, ymm14, ymm14
    | 1 | | | | | | | 1.0 | | | dec rcx
    | 0F | | | | | | | | | | jnz 0xffffffffffffffaa
    Total Num Of Uops: 16
  • 我按照jcomeau_ictx的想法,修改了Agner Fog的testp.zip(2015-12-22发布)
    BDW 306D4 上的端口使用情况:
               Clock   Core cyc   Instruct      uop p0     uop p1     uop p5     uop p6 
    Code1: 7734720 7734727 17000001 4983410 5016592 5000001 1000001
    Code2: 5000072 5000072 17000001 5000010 5000014 4999978 1000002

    港口分布与 Haswell 上的一样近乎完美。然后我检查了
    资源停止计数器(事件 0xa2)
              Clock   Core cyc   Instruct      res.stl.   RS stl.    SB stl.    ROB stl.
    Code1: 7736212 7736213 17000001 3736191 3736143 0 0
    Code2: 5000068 5000072 17000001 1000050 999957 0 0

    在我看来,来自 RS 摊位的 Code1 和 Code2 差异。
    来自英特尔 SDM 的评论:“由于没有符合条件的 RS 条目,周期停止
    可用的。”

    我怎样才能避免使用 FMA 的这种失速?

    更新5:

  • Code6 发生了变化,正如 Peter Cordes 引起我的注意,只有 vpaddds 使用内存操作数。对 HSW 和 SKL 没有影响,BDW 变得更糟。
  • 正如 Marat Dukhan 测量的那样,不仅 vpadd/vpsub/vpand/vpandn/vpxor 受到影响,还有其他 Port5 有界指令,如 vmovaps、vblendps、vpermps、vshufps、vbroadcastss;
  • 正如 IwillnotexistIdonotexist 建议的那样,我尝试了其他操作数。一个成功的修改是 Code7,其中所有 vpaddd 都使用 ymm15。这个版本可以在 BDW 上产生约 5000000 个时钟,但只是一段时间。在约 600 万个 FMA 对之后,它达到通常的约 7730000 个时钟:
    Clock   Core cyc   Instruct   res.stl.   RS stl.     SB stl.    ROB stl.
    5133724 5110723 17000001 1107998 946376 0 0
    6545476 6545482 17000001 2545453 1 0 0
    6545468 6545471 17000001 2545437 90910 0 0
    5000016 5000019 17000001 999992 999992 0 0
    7671620 7617127 17000003 3614464 3363363 0 0
    7737340 7737345 17000001 3737321 3737259 0 0
    7802916 7747108 17000003 3737478 3735919 0 0
    7928784 7796057 17000007 3767962 3676744 0 0
    7941072 7847463 17000003 3781103 3651595 0 0
    7787812 7779151 17000005 3765109 3685600 0 0
    7792524 7738029 17000002 3736858 3736764 0 0
    7736000 7736007 17000001 3735983 3735945 0 0
  • 我尝试了 Code7 的 xmm 版本作为 Code8。效果类似,但运行时间越快,持续时间越长。我没有发现 1.6GHz i5-5250U 和 3.7GHz i7-5775C 之间有显着差异。
  • 16 和 17 是在禁用超线程的情况下制作的。启用 HTT 后效果会更小。
  • 最佳答案

    更新:以前的版本包含一个 6 VPADDD说明(与问题中的 5 相比),以及额外的 VPADDD造成Broadwell的不平衡。修复后,Haswell、Broadwell 和 Skylake 向端口 0、1 和 5 发出几乎相同数量的微指令。

    没有端口污染,但是 uops 的调度不是最理想的,大多数 uops 都流向 Broadwell 的 5 号端口,并在 0 号和 1 号端口饱和之前使其成为瓶颈。

    为了演示发生了什么,我建议 (ab) 使用 PeachPy.IO 上的演示:

  • 在谷歌浏览器中打开 www.peachpy.io(在其他浏览器中无法使用)。
  • 用下面的代码替换默认代码(实现 SDOT 功能),这实际上是移植到 PeachPy 的示例句法:
    n = Argument(size_t)
    x = Argument(ptr(const_float_))
    incx = Argument(size_t)
    y = Argument(ptr(const_float_))
    incy = Argument(size_t)

    with Function("sdot", (n, x, incx, y, incy)) as function:
    reg_n = GeneralPurposeRegister64()
    LOAD.ARGUMENT(reg_n, n)

    VZEROALL()

    with Loop() as loop:
    for i in range(15):
    ymm_i = YMMRegister(i)
    if i < 10:
    VFMADD231PS(ymm_i, ymm_i, ymm_i)
    else:
    VPADDD(ymm_i, ymm_i, ymm_i)
    DEC(reg_n)
    JNZ(loop.begin)

    RETURN()
  • 我有许多不同微架构上的机器作为 PeachPy.io 的后端。选择 Intel Haswell、Intel Broadwell 或 Intel Skylake,然后按“快速运行”。系统将编译您的代码,将其上传到服务器,并可视化执行期间收集的性能计数器。
  • 这是 Intel Haswell 上执行端口上的 uops 分布:

  • Port pressure on Intel Haswell
  • 这是来自 Intel Broadwell 的相同情节:

  • Port pressure on Intel Broadwell
  • 显然,无论 uops 调度程序的缺陷是什么,它都已在 Intel Skylake 中修复,因为该机器上的端口压力与 Haswell 上的相同。
  • 关于performance - 英特尔 Broadwell 处理器出现明显的 FMA 性能异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34309707/

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