我发现了一个有趣的功能强大的工具IACA (the Intel Architecture Code Analyzer),但是我很难理解它。我该怎么办,它的局限性是什么,我该如何:

  • 使用它来分析C或C++中的代码吗?
  • 用它来分析x86汇编器中的代码吗?
  • 最佳答案


    这是什么:
    IACA (the Intel Architecture Code Analyzer)是一款免费软件,由英特尔公司提供的开源静态分析工具( 2019年:生命周期终止),用于在现代英特尔处理器执行时静态分析指令调度。这样一来,它就可以针对给定的代码段计算出

  • 吞吐量模式中,最大吞吐量(假定该片段为最内部循环的主体)
  • 延迟模式中,从第一条指令到最后一条指令的最小延迟。
  • 跟踪模式中,打印指令在其管道阶段的进度。

  • 在假定最佳执行条件时(所有内存访问都命中L1高速缓存,并且没有页面错误)。
    IACA支持从2.3版开始的Nehalem,Westmere,Sandy Bridge,Ivy Bridge,Haswell,Broadwell和Skylake处理器以及从3.0版开始的Haswell,Broadwell和Skylake的计算调度。
    IACA是一个命令行工具,可生成ASCII文本报告和Graphviz图。 2.1版及以下版本支持32位和64位Linux,Mac OS X和Windows以及32位和64位代码的分析; 2.2版及更高版本仅支持64位操作系统和64位代码分析。
    如何使用它:
    IACA的输入是代码的已编译二进制文件,其中已注入(inject)了两个标记:开始标记和结束标记。标记使代码无法运行,但是允许该工具快速找到相关的代码段并对其进行分析。
    您不需要在系统上运行二进制文件的能力。实际上,由于代码中存在注入(inject)的标记,提供给IACA的二进制文件始终无法运行。 IACA仅要求具有读取要分析的二进制文件的能力。因此,可以使用IACA在奔腾III机器上使用FMA指令分析Haswell二进制文件。
    C/C++
    在C和C++中,可以使用#include "iacaMarks.h"来访问注入(inject)标记的宏,其中iacaMarks.hinclude/子目录中的工具随附的 header 。
    然后,将标记插入到感兴趣的最里面的循环或感兴趣的直线块周围,如下所示:
    /* C or C++ usage of IACA */
    
    while(cond){
        IACA_START
        /* Loop body */
        /* ... */
    }
    IACA_END
    
    然后按照启用优化的方式重新构建应用程序(对于IDE用户(如Visual Studio),在 Release模式下)。输出是二进制文件,在所有方面都与Release版本完全相同,除了存在标记之外,这些标记使应用程序无法运行。
    IACA依靠编译器不对标记进行过多的排序;这样,对于此类构建,如果某些功能强大的优化将标记重新排序以包括不在最内层循环内的无关代码,或排除其中的代码,则可能需要禁用这些功能。
    组装(x86)
    IACA的标记是在代码中正确位置注入(inject)的魔术字节模式。在C或C++中使用iacaMarks.h时,编译器会处理在正确的位置插入 header 指定的魔术字节。但是,在组装时,必须手动插入这些标记。因此,必须执行以下操作:
        ; NASM usage of IACA
    
        mov ebx, 111          ; Start marker bytes
        db 0x64, 0x67, 0x90   ; Start marker bytes
    
    .innermostlooplabel:
        ; Loop body
        ; ...
        jne .innermostlooplabel ; Conditional branch backwards to top of loop
    
        mov ebx, 222          ; End marker bytes
        db 0x64, 0x67, 0x90   ; End marker bytes
    
    对于C/C++程序员来说,编译器必须达到相同的模式至关重要。
    它输出什么:
    例如,让我们分析following assembler example on the Haswell architecture:
    .L2:
        vmovaps         ymm1, [rdi+rax] ;L2
        vfmadd231ps     ymm1, ymm2, [rsi+rax] ;L2
        vmovaps         [rdx+rax], ymm1 ; S1
        add             rax, 32         ; ADD
        jne             .L2             ; JMP
    
    我们在.L2标签之前添加开始标记,并在jne标签之后添加结束标记。然后,我们重新构建软件并调用IACA(在Linux上,假定bin/目录位于路径中,并且foo是包含IACA标记的ELF64对象):
    iaca.sh -64 -arch HSW -graph insndeps.dot foo
    
    ,从而生成在Haswell处理器上运行时64位二进制foo的分析报告,以及可通过Graphviz查看的指令依存关系图。
    该报告将打印到标准输出中(尽管可以使用-o开关将其定向到文件中)。以上代码段的报告为:
    Intel(R) Architecture Code Analyzer Version - 2.1
    Analyzed File - ../../../tests_fma
    Binary Format - 64Bit
    Architecture  - HSW
    Analysis Type - Throughput
    
    Throughput Analysis Report
    --------------------------
    Block Throughput: 1.55 Cycles       Throughput Bottleneck: FrontEnd, PORT2_AGU, PORT3_AGU
    
    Port Binding In Cycles Per Iteration:
    ---------------------------------------------------------------------------------------
    |  Port  |  0   -  DV  |  1   |  2   -  D   |  3   -  D   |  4   |  5   |  6   |  7   |
    ---------------------------------------------------------------------------------------
    | Cycles | 0.5    0.0  | 0.5  | 1.5    1.0  | 1.5    1.0  | 1.0  | 0.0  | 1.0  | 0.0  |
    ---------------------------------------------------------------------------------------
    
    N - port number or number of cycles resource conflict caused delay, DV - Divider pipe (on port 0)
    D - Data fetch pipe (on ports 2 and 3), CP - on a critical path
    F - Macro Fusion with the previous instruction occurred
    * - instruction micro-ops not bound to a port
    ^ - Micro Fusion happened
    # - ESP Tracking sync uop was issued
    @ - SSE instruction followed an AVX256 instruction, dozens of cycles penalty is expected
    ! - instruction not supported, was not accounted in Analysis
    
    | Num Of |                    Ports pressure in cycles                     |    |
    |  Uops  |  0  - DV  |  1  |  2  -  D  |  3  -  D  |  4  |  5  |  6  |  7  |    |
    ---------------------------------------------------------------------------------
    |   1    |           |     | 1.0   1.0 |           |     |     |     |     | CP | vmovaps ymm1, ymmword ptr [rdi+rax*1]
    |   2    | 0.5       | 0.5 |           | 1.0   1.0 |     |     |     |     | CP | vfmadd231ps ymm1, ymm2, ymmword ptr [rsi+rax*1]
    |   2    |           |     | 0.5       | 0.5       | 1.0 |     |     |     | CP | vmovaps ymmword ptr [rdx+rax*1], ymm1
    |   1    |           |     |           |           |     |     | 1.0 |     |    | add rax, 0x20
    |   0F   |           |     |           |           |     |     |     |     |    | jnz 0xffffffffffffffec
    Total Num Of Uops: 6
    
    该工具有用地指出,目前的瓶颈是Haswell前端和端口2和3的AGU。此示例使我们能够诊断问题,因为端口7未在处理该商店,并采取了补救措施。
    局限性:
    IACA不支持某些说明,在分析中将忽略这些说明。它不支持早于Nehalem的处理器,并且不支持吞吐量模式下的非最内层循环(无法猜测以哪个频率和哪种模式执行哪个分支)。

    关于c++ - 什么是IACA?如何使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26021337/

    10-12 20:57