当前位置: 首页 > 知识库问答 >
问题:

什么是IACA以及我如何使用它?

祝昊东
2023-03-14
  • 使用它来分析C或C++中的代码?
  • 使用它来分析x86汇编程序中的代码?

共有1个答案

屠嘉
2023-03-14

2019-04年:达到EOL。建议的替代方案:LLVM-MCA

2017-11年:3.0版本发布(最新截至2019-05-18)

2017-03年:2.3版发布

    null

IACA是一个生成ASCII文本报告和Graphviz图的命令行工具。2.1及以下版本支持32位和64位Linux、Mac OS X和Windows以及32位和64位代码的分析;版本2.2及以上仅支持64位操作系统和64位代码的分析。

IACA的输入是您的代码的一个已编译的二进制文件,其中注入了两个标记:开始标记和结束标记。标记使代码无法运行,但允许工具快速找到相关的代码片段并对其进行分析。

您不需要在系统上运行二进制文件;事实上,由于代码中存在注入的标记,提供给IACA的二进制文件无论如何都无法运行。IACA只要求能够读取要分析的二进制文件。因此,可以使用IACA在Pentium III机器上使用FMA指令分析Haswell二进制。

在C和C++中,您可以通过#include“iacamarks.h”访问标记注入宏,其中iacamarks.h是工具附带在include/子目录中的头。

然后在最内部的感兴趣循环(或感兴趣的直线块)周围插入标记,如下所示:

/* C or C++ usage of IACA */

while(cond){
    IACA_START
    /* Loop body */
    /* ... */
}
IACA_END

然后重新构建应用程序,就像它在启用优化的情况下一样(对于IDE(如Visual Studio)的用户,在发布模式下)。输出是一个二进制文件,它在所有方面都与发行版版本相同,除了标记的存在,这些标记使应用程序不可运行。

IACA依赖于编译器不对标记进行过度的重新排序;因此,对于这样的分析构建,如果对标记进行重新排序以包括不在最内部循环中的无关代码,或者排除其中的代码,则可能需要禁用某些强大的优化。

IACA的标记是在代码中的正确位置注入的神奇字节模式。在C或C++中使用iacamarks.h时,编译器处理在正确位置插入头指定的神奇字节。但是,在程序集中,必须手动插入这些标记。因此,必须做到以下几点:

    ; 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++程序员来说,编译器实现同样的模式是非常关键的。

作为示例,让我们分析一下Haswell架构上的汇编程序示例:

.L2:
    vmovaps         ymm1, [rdi+rax] ;L2
    vfmadd231ps     ymm1, ymm2, [rsi+rax] ;L2
    vmovaps         [rdx+rax], ymm1 ; S1
    add             rax, 32         ; ADD
    jne             .L2             ; JMP
iaca.sh -64 -arch HSW -graph insndeps.dot foo

报告将打印为标准输出(尽管它可能被定向到具有-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的处理器,也不支持吞吐量模式下的非最内部循环(无法猜测哪个分支被采用的频率和模式)。

 类似资料:
  • 问题内容: 我参与开发一个Java项目,该项目使用一些C ++组件,因此我需要Jacob.dll。(在Windows 7上) 无论我把Jacob.dll放在哪里,我都在不断获取。 我在寻找可能的决定,而到目前为止尚未尝试的决定是设置LD_LIBRARY_PATH变量,指向.dll文件。 我经验不足,不熟悉该变量的含义和用法-您能帮我吗? 问题答案: 通常,您必须在JVM的命令行上进行设置:

  • 问题内容: 经常出现在Python模块中。即使阅读了Python的文档,我也不明白它的用途以及使用时间/方式。 有人可以举例说明吗? 关于我收到的基本用法的一些答案似乎是正确的。 但是,我需要了解有关工作原理的另一件事: 对我来说,最令人困惑的概念是当前的python版本如何包含未来版本的功能,以及如何使用当前版本的Python成功地编译使用未来版本的功能的程序。 我猜想当前版本包含了将来的潜在功

  • 问题内容: 我想创建一个Android应用程序,以作者身份上传我的大学笔记,任何人都可以下载它。我读到firebase可以帮助我解决这个问题。任何人都可以参考一下来解释什么是firebase,以及如何使用它。谢谢! 问题答案: Firebase团队成员在这里。 tl; dr- 阅读此快速入门,观看此视频。使用FirebaseUI。 Firebase是用于移动和Web应用程序的平台。 Firebas

  • 我读了很多关于@JoinColumn的文章,但我仍然不明白它背后的想法。 病人床 车辆表 我一直在读这篇文章,但我仍然感到困惑。JPA JoinColumn与mappedBy

  • 问题内容: 我已经阅读了很多有关@JoinColumn的内容,但是我仍然不明白它的含义。 患者表 车辆表 患者分类 车辆类别 Vehicle Class ---- Entity @JoinColumn(name=”patient_id”) ---- annotation private Patient patient ----field ``` 会说吗?该车辆实体有一个外键到患者实体命名patie

  • 问题内容: 我是Flask的新手。我不明白怎么用。我在某处读到它用于返回查询字符串的值[如果我错了,请纠正我]。以及需要多少个参数。我知道当我必须存储提交的表单数据时,我可以使用 在此,仅传递一个参数。 考虑下面的代码。分页也已在此代码中完成。 在这里,request.args.get()采用两个参数。请解释为什么要使用两个参数以及它的用途。 问题答案: 根据flask.Request.args文