• 代码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不归零):
    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会发生什么吗?我的猜测是
    在Code1案例中,Broadwell以某种方式用vpaddds污染了Port1,但是
    Haswell仅在Port0和Port1已满的情况下才能使用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的想法(用其他指令(vpxor,vpor,vpand,vpandn,vpsubd代替vpaddd))。如果新指令不是调零惯用语(带有相同寄存器的vpxor,vpsubd),则BDW上的结果相同。示例项目已用Code4和Code5更新。

    更新4:

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

    performance - 英特尔Broadwell处理器遇到明显的FMA性能异常-LMLPHP
  • 英特尔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 / vpx的影响,而且受Port5限制的其他指令,例如vmovaps,vblendps,vpermps,vshufps,vbroadcastss;
  • 如IwillnotexistIdonotexist所建议,我尝试了其他操作数。一个成功的修改是Code7,其中所有vpaddds都使用ymm15。这个版本可以在BDW上产生约500万个clks,但是只是一会儿。在大约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后,效果会更差。
  • 最佳答案

    更新

    自从我使用Haswell以来,我没有给您任何解释,但是我确实有共享的代码可以帮助您或使用Broadwell或Skylake硬件的其他人隔离您的问题。如果可以在您的计算机上运行它并共享结果,我们可以深入了解您的计算机正在发生什么。

    介绍

    最新的Intel Core i7处理器具有7个性能监视器计数器(PMC),3个固定功能和4个通用,可用于配置代码。固定功能的PMC为:

  • 说明已退休
  • 不停止的核心周期(时钟滴答声,包括TurboBoost的影响)
  • 未停止的引用周期(固定频率的时钟滴答)

  • 核心:引用时钟周期的比率决定了动态频率缩放的相对加速或减速。

    尽管存在访问这些计数器的软件(请参见下面的评论),但我不知道它们,但仍然发现它们的粒度不够。

    因此,在过去的几天里,我为自己编写了一个Linux内核模块perfcount,以授予我对Intel性能计数器监视器的访问权限,并为您的代码提供了一个用户空间测试台和库,该库将FMA代码包装在对LKM的调用周围。有关如何重现我的设置的说明如下。

    我的testbench源代码如下。它会预热,然后运行您的代码几次,并在一长列指标上对其进行测试。我将您的循环计数更改为10亿。因为一次只能编程4个通用PMC,所以我一次要进行4次测量。
    perfcountdemo.c
    /* Includes */
    #include "libperfcount.h"
    #include <ctype.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    /* Function prototypes */
    void code1(void);
    void code2(void);
    void code3(void);
    void code4(void);
    void code5(void);
    
    /* Global variables */
    void ((*FN_TABLE[])(void)) = {
        code1,
        code2,
        code3,
        code4,
        code5
    };
    
    
    /**
     * Code snippets to bench
     */
    
    void code1(void){
        asm volatile(
        ".intel_syntax noprefix\n\t"
        "vzeroall\n\t"
        "mov             rcx, 1000000000\n\t"
        "LstartLabel1:\n\t"
        "vfmadd231ps     %%ymm0, %%ymm0, %%ymm0\n\t"
        "vfmadd231ps     ymm1, ymm1, ymm1\n\t"
        "vfmadd231ps     ymm2, ymm2, ymm2\n\t"
        "vfmadd231ps     ymm3, ymm3, ymm3\n\t"
        "vfmadd231ps     ymm4, ymm4, ymm4\n\t"
        "vfmadd231ps     ymm5, ymm5, ymm5\n\t"
        "vfmadd231ps     ymm6, ymm6, ymm6\n\t"
        "vfmadd231ps     ymm7, ymm7, ymm7\n\t"
        "vfmadd231ps     ymm8, ymm8, ymm8\n\t"
        "vfmadd231ps     ymm9, ymm9, ymm9\n\t"
        "vpaddd          ymm10, ymm10, ymm10\n\t"
        "vpaddd          ymm11, ymm11, ymm11\n\t"
        "vpaddd          ymm12, ymm12, ymm12\n\t"
        "vpaddd          ymm13, ymm13, ymm13\n\t"
        "vpaddd          ymm14, ymm14, ymm14\n\t"
        "dec             rcx\n\t"
        "jnz             LstartLabel1\n\t"
        ".att_syntax noprefix\n\t"
        : /* No outputs we care about */
        : /* No inputs we care about */
        : "xmm0",  "xmm1",  "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",  "xmm7",
          "xmm8",  "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
          "rcx",
          "memory"
        );
    }
    void code2(void){
    
    }
    void code3(void){
    
    }
    void code4(void){
    
    }
    void code5(void){
    
    }
    
    
    
    /* Test Schedule */
    const char* const SCHEDULE[] = {
        /* Batch */
        "uops_issued.any",
        "uops_issued.any<1",
        "uops_issued.any>=1",
        "uops_issued.any>=2",
        /* Batch */
        "uops_issued.any>=3",
        "uops_issued.any>=4",
        "uops_issued.any>=5",
        "uops_issued.any>=6",
        /* Batch */
        "uops_executed_port.port_0",
        "uops_executed_port.port_1",
        "uops_executed_port.port_2",
        "uops_executed_port.port_3",
        /* Batch */
        "uops_executed_port.port_4",
        "uops_executed_port.port_5",
        "uops_executed_port.port_6",
        "uops_executed_port.port_7",
        /* Batch */
        "resource_stalls.any",
        "resource_stalls.rs",
        "resource_stalls.sb",
        "resource_stalls.rob",
        /* Batch */
        "uops_retired.all",
        "uops_retired.all<1",
        "uops_retired.all>=1",
        "uops_retired.all>=2",
        /* Batch */
        "uops_retired.all>=3",
        "uops_retired.all>=4",
        "uops_retired.all>=5",
        "uops_retired.all>=6",
        /* Batch */
        "inst_retired.any_p",
        "inst_retired.any_p<1",
        "inst_retired.any_p>=1",
        "inst_retired.any_p>=2",
        /* Batch */
        "inst_retired.any_p>=3",
        "inst_retired.any_p>=4",
        "inst_retired.any_p>=5",
        "inst_retired.any_p>=6",
        /* Batch */
        "idq_uops_not_delivered.core",
        "idq_uops_not_delivered.core<1",
        "idq_uops_not_delivered.core>=1",
        "idq_uops_not_delivered.core>=2",
        /* Batch */
        "idq_uops_not_delivered.core>=3",
        "idq_uops_not_delivered.core>=4",
        "rs_events.empty",
        "idq.empty",
        /* Batch */
        "idq.mite_all_uops",
        "idq.mite_all_uops<1",
        "idq.mite_all_uops>=1",
        "idq.mite_all_uops>=2",
        /* Batch */
        "idq.mite_all_uops>=3",
        "idq.mite_all_uops>=4",
        "move_elimination.int_not_eliminated",
        "move_elimination.simd_not_eliminated",
        /* Batch */
        "lsd.uops",
        "lsd.uops<1",
        "lsd.uops>=1",
        "lsd.uops>=2",
        /* Batch */
        "lsd.uops>=3",
        "lsd.uops>=4",
        "ild_stall.lcp",
        "ild_stall.iq_full",
        /* Batch */
        "br_inst_exec.all_branches",
        "br_inst_exec.0x81",
        "br_inst_exec.0x82",
        "icache.misses",
        /* Batch */
        "br_misp_exec.all_branches",
        "br_misp_exec.0x81",
        "br_misp_exec.0x82",
        "fp_assist.any",
        /* Batch */
        "cpu_clk_unhalted.core_clk",
        "cpu_clk_unhalted.ref_xclk",
        "baclears.any"
    
    };
    const int NUMCOUNTS = sizeof(SCHEDULE)/sizeof(*SCHEDULE);
    
    
    /**
     * Main
     */
    
    int main(int argc, char* argv[]){
        int i;
    
        /**
         * Initialize
         */
    
        pfcInit();
        if(argc <= 1){
            pfcDumpEvents();
            exit(1);
        }
        pfcPinThread(3);
    
    
        /**
         * Arguments are:
         *
         *     perfcountdemo #codesnippet
         *
         * There is a schedule of configuration that is followed.
         */
    
        void (*fn)(void) = FN_TABLE[strtoull(argv[1], NULL, 0)];
        static const uint64_t ZERO_CNT[7] = {0,0,0,0,0,0,0};
        static const uint64_t ZERO_CFG[7] = {0,0,0,0,0,0,0};
    
        uint64_t cnt[7]                   = {0,0,0,0,0,0,0};
        uint64_t cfg[7]                   = {2,2,2,0,0,0,0};
    
        /* Warmup */
        for(i=0;i<10;i++){
            fn();
        }
    
        /* Run master loop */
        for(i=0;i<NUMCOUNTS;i+=4){
            /* Configure counters */
            const char* sched0 = i+0 < NUMCOUNTS ? SCHEDULE[i+0] : "";
            const char* sched1 = i+1 < NUMCOUNTS ? SCHEDULE[i+1] : "";
            const char* sched2 = i+2 < NUMCOUNTS ? SCHEDULE[i+2] : "";
            const char* sched3 = i+3 < NUMCOUNTS ? SCHEDULE[i+3] : "";
            cfg[3] = pfcParseConfig(sched0);
            cfg[4] = pfcParseConfig(sched1);
            cfg[5] = pfcParseConfig(sched2);
            cfg[6] = pfcParseConfig(sched3);
    
            pfcWrConfigCnts(0, 7, cfg);
            pfcWrCountsCnts(0, 7, ZERO_CNT);
            pfcRdCountsCnts(0, 7, cnt);
            /* ^ Should report 0s, and launch the counters. */
            /************** Hot section **************/
            fn();
            /************ End Hot section ************/
            pfcRdCountsCnts(0, 7, cnt);
            pfcWrConfigCnts(0, 7, ZERO_CFG);
            /* ^ Should clear the counter config and disable them. */
    
            /**
             * Print the lovely results
             */
    
            printf("Instructions Issued                : %20llu\n", cnt[0]);
            printf("Unhalted core cycles               : %20llu\n", cnt[1]);
            printf("Unhalted reference cycles          : %20llu\n", cnt[2]);
            printf("%-35s: %20llu\n", sched0, cnt[3]);
            printf("%-35s: %20llu\n", sched1, cnt[4]);
            printf("%-35s: %20llu\n", sched2, cnt[5]);
            printf("%-35s: %20llu\n", sched3, cnt[6]);
        }
    
        /**
         * Close up shop
         */
    
        pfcFini();
    }
    

    在我的机器上,我得到以下结果:

    Haswell Core i7-4700MQ
    > ./perfcountdemo 0
    Instructions Issued                :          17000001807
    Unhalted core cycles               :           5305920785
    Unhalted reference cycles          :           4245764952
    uops_issued.any                    :          16000811079
    uops_issued.any<1                  :           1311417889
    uops_issued.any>=1                 :           4000292290
    uops_issued.any>=2                 :           4000229358
    Instructions Issued                :          17000001806
    Unhalted core cycles               :           5303822082
    Unhalted reference cycles          :           4243345896
    uops_issued.any>=3                 :           4000156998
    uops_issued.any>=4                 :           4000110067
    uops_issued.any>=5                 :                    0
    uops_issued.any>=6                 :                    0
    Instructions Issued                :          17000001811
    Unhalted core cycles               :           5314227923
    Unhalted reference cycles          :           4252020624
    uops_executed_port.port_0          :           5016261477
    uops_executed_port.port_1          :           5036728509
    uops_executed_port.port_2          :                 5282
    uops_executed_port.port_3          :                12481
    Instructions Issued                :          17000001816
    Unhalted core cycles               :           5329351248
    Unhalted reference cycles          :           4265809728
    uops_executed_port.port_4          :                 7087
    uops_executed_port.port_5          :           4946019835
    uops_executed_port.port_6          :           1000228324
    uops_executed_port.port_7          :                 1372
    Instructions Issued                :          17000001816
    Unhalted core cycles               :           5325153463
    Unhalted reference cycles          :           4261060248
    resource_stalls.any                :           1322734589
    resource_stalls.rs                 :            844250210
    resource_stalls.sb                 :                    0
    resource_stalls.rob                :                    0
    Instructions Issued                :          17000001814
    Unhalted core cycles               :           5327823817
    Unhalted reference cycles          :           4262914728
    uops_retired.all                   :          16000445793
    uops_retired.all<1                 :            687284798
    uops_retired.all>=1                :           4646263984
    uops_retired.all>=2                :           4452324050
    Instructions Issued                :          17000001809
    Unhalted core cycles               :           5311736558
    Unhalted reference cycles          :           4250015688
    uops_retired.all>=3                :           3545695253
    uops_retired.all>=4                :           3341664653
    uops_retired.all>=5                :                 1016
    uops_retired.all>=6                :                    1
    Instructions Issued                :          17000001871
    Unhalted core cycles               :           5477215269
    Unhalted reference cycles          :           4383891984
    inst_retired.any_p                 :          17000001871
    inst_retired.any_p<1               :            891904306
    inst_retired.any_p>=1              :           4593972062
    inst_retired.any_p>=2              :           4441024510
    Instructions Issued                :          17000001835
    Unhalted core cycles               :           5377202052
    Unhalted reference cycles          :           4302895152
    inst_retired.any_p>=3              :           3555852364
    inst_retired.any_p>=4              :           3369559466
    inst_retired.any_p>=5              :            999980244
    inst_retired.any_p>=6              :                    0
    Instructions Issued                :          17000001826
    Unhalted core cycles               :           5349373678
    Unhalted reference cycles          :           4280991912
    idq_uops_not_delivered.core        :              1580573
    idq_uops_not_delivered.core<1      :           5354931839
    idq_uops_not_delivered.core>=1     :               471248
    idq_uops_not_delivered.core>=2     :               418625
    Instructions Issued                :          17000001808
    Unhalted core cycles               :           5309687640
    Unhalted reference cycles          :           4248083976
    idq_uops_not_delivered.core>=3     :               280800
    idq_uops_not_delivered.core>=4     :               247923
    rs_events.empty                    :                    0
    idq.empty                          :               649944
    Instructions Issued                :          17000001838
    Unhalted core cycles               :           5392229041
    Unhalted reference cycles          :           4315704216
    idq.mite_all_uops                  :              2496139
    idq.mite_all_uops<1                :           5397877484
    idq.mite_all_uops>=1               :               971582
    idq.mite_all_uops>=2               :               595973
    Instructions Issued                :          17000001822
    Unhalted core cycles               :           5347205506
    Unhalted reference cycles          :           4278845208
    idq.mite_all_uops>=3               :               394011
    idq.mite_all_uops>=4               :               335205
    move_elimination.int_not_eliminated:                    0
    move_elimination.simd_not_eliminated:                    0
    Instructions Issued                :          17000001812
    Unhalted core cycles               :           5320621549
    Unhalted reference cycles          :           4257095280
    lsd.uops                           :          15999287982
    lsd.uops<1                         :           1326629729
    lsd.uops>=1                        :           3999821996
    lsd.uops>=2                        :           3999821996
    Instructions Issued                :          17000001813
    Unhalted core cycles               :           5320533147
    Unhalted reference cycles          :           4257105096
    lsd.uops>=3                        :           3999823498
    lsd.uops>=4                        :           3999823498
    ild_stall.lcp                      :                    0
    ild_stall.iq_full                  :                 3468
    Instructions Issued                :          17000001813
    Unhalted core cycles               :           5323278281
    Unhalted reference cycles          :           4258969200
    br_inst_exec.all_branches          :           1000016626
    br_inst_exec.0x81                  :           1000016616
    br_inst_exec.0x82                  :                    0
    icache.misses                      :                  294
    Instructions Issued                :          17000001812
    Unhalted core cycles               :           5315098728
    Unhalted reference cycles          :           4253082504
    br_misp_exec.all_branches          :                    5
    br_misp_exec.0x81                  :                    2
    br_misp_exec.0x82                  :                    0
    fp_assist.any                      :                    0
    Instructions Issued                :          17000001819
    Unhalted core cycles               :           5338484610
    Unhalted reference cycles          :           4271432976
    cpu_clk_unhalted.core_clk          :           5338494250
    cpu_clk_unhalted.ref_xclk          :            177976806
    baclears.any                       :                    1
                                       :                    0
    

    我们可能会看到,在Haswell上,一切都做得很好。我将根据以上统计信息做一些说明:
  • 发布的说明对我而言是一致的。它始终围绕17000001800,这是一个好兆头:这意味着我们可以很好地估算我们的开销。同上其他固定功能计数器。它们都匹配得很好的事实意味着,每批4个测试是苹果对苹果的比较。
  • 的核心:引用周期比率为5305920785/4245764952,我们得到的平均频率换算约为1.25;根据我的观察,我的核心频率从2.4 GHz上升到3.0 GHz,这非常好。 cpu_clk_unhalted.core_clk/(10.0*cpu_clk_unhalted.ref_xclk)的频率也低于3 GHz。
  • 发出的指令与核心周期的比值给出了IPC 17000001807/5305920785〜3.20,这也是正确的:每个时钟周期2个FMA + 1 VPADDD(4个时钟周期),以及每第5个时钟周期2条额外的循环控制指令在平行下。
  • uops_issued.any:发出的指令数为〜17B,但是发出的指令数为〜16B。这是因为用于循环控制的两条指令融合在一起了;好兆头。此外,在5.3B(占25%的时间)中有1.3B时钟周期左右,没有发出任何微指令,而其余时间(4B时钟周期)几乎全部合计,一次发出4微秒。
  • uops_executed_port.port_[0-7]:端口饱和。我们 body 健康。在16B融合后的uops中,端口0、1和5在5.3B周期内分别吃了5B uops(这意味着它们的分布是最优的:分别是float,float和int),Port 6则是1B(融合的dec-branch op)和端口2、3、4和7相比,可以忽略不计。
  • resource_stalls:它们发生了1.3B,其中的2/3是由于保留站(RS)造成的,另外三分之一是未知原因造成的。
  • 从我们对uops_retired.allinst_retired.all进行比较所建立的累积分布中,我们知道我们将在60%的时间内退出4 uos,在13%的时间内退出0 uos,在其余时间中退出2 uops,否则数量可忽略不计。
  • (许多*idq*计数):IDQ很少阻止我们。
  • lsd:循环流检测器正在运行;从前端向前端提供了将近16B熔融的微指令。
  • ild:指令长度解码不是瓶颈,并且不会遇到单个长度改变前缀。
  • br_inst_exec/br_misp_exec:分支预测错误是可以忽略的问题。
  • icache.misses:可以忽略。
  • fp_assist:可以忽略。没有遇到异常。 (我相信,如果没有DAZ异常为零冲洗,则需要帮助,应在此处注册)

  • 因此,在英特尔Haswell平台上,一切进展顺利。如果您可以在您的计算机上运行我的套件,那将很好。

    复制说明
  • 规则#1:在执行任何操作之前,请检查我的所有代码。永远不要盲目地信任Internet上的陌生人。
  • 抓取perfcountdemo.clibperfcount.clibperfcount.h,将它们放在同一目录中并一起编译。
  • 抓取perfcount.cMakefile,将它们放在同一目录中,并make内核模块。
  • 使用GRUB引导标志nmi_watchdog=0 modprobe.blacklist=iTCO_wdt,iTCO_vendor_support重新引导计算机。否则,NMI看门狗将篡改未停止的核心周期计数器。
  • insmod perfcount.ko模块。 dmesg | tail -n 10应该说它已成功加载,并说有3个Ff计数器和4个Gp计数器,否则给出失败的原因。
  • 运行我的应用程序,最好在系统的其余部分未加载时运行。还尝试通过将参数更改为perfcountdemo.c来更改pfcPinThread()中限制亲和力的核心。
  • 在此处编辑结果。
  • 08-16 12:10