¿Qué es IACA y cómo lo uso?


He encontrado esta herramienta interesante y poderosa llamada IACA (el Analizador de Código de Arquitectura Intel), pero tengo problemas para entenderlo. ¿Qué puedo hacer con él, cuáles son sus limitaciones y cómo puedo:

  • ¿Usarlo para analizar código en C o C++?
  • ¿Usarlo para analizar código en el ensamblador x86?
Author: Iwillnotexist Idonotexist, 2014-09-24

1 answers

2017-11: Versión 3.0 publicado (la última, de 2017-11-03)

2017-03: Versión 2.3 publicado

Qué es:

IACA (Intel Architecture Code Analyzer) es una herramienta gratuita de análisis estático de código cerrado hecha por Intel para analizar estáticamente la programación de instrucciones cuando se ejecuta por procesadores Intel modernos. Esto le permite calcular, para un determinado snippet,

  • En Modo de rendimiento , el rendimiento máximo (se asume que el fragmento es el cuerpo de un bucle más interno)
  • En el modo de latencia , la latencia mínima desde la primera instrucción hasta la última.
  • En Modo Trace, imprime el progreso de las instrucciones a través de sus etapas de canalización.

Al asumir condiciones de ejecución óptimas (Todos los accesos a la memoria golpean la caché L1 y no hay página falla).

IACA soporta programaciones de computación para los procesadores Nehalem, Westmere, Sandy Bridge, Ivy Bridge, Haswell, Broadwell y Skylake a partir de la versión 2.3 y Haswell, Broadwell y Skylake a partir de la versión 3.0.

IACA es una herramienta de línea de comandos que produce informes de texto ASCII y diagramas de Graphviz. Las versiones 2.1 y posteriores soportaban Linux de 32 y 64 bits, Mac OS X y Windows y análisis de código de 32 bits y 64 bits; la versión 2.2 y posteriores solo admiten sistemas operativos de 64 bits y análisis de Código de 64 bits.

Cómo usarlo:

La entrada de IACA es un binario compilado de su código, en el que se han inyectado dos marcadores: un marcador de inicio y un marcador final. Los marcadores hacen que el código no se pueda ejecutar, pero permiten que la herramienta encuentre rápidamente las piezas de código relevantes y las analice.

No necesita la capacidad de ejecutar el binario en su sistema; De hecho, el binario suministrado a IACA no puede funcionar de todos modos debido a la presencia de los marcadores inyectados en el código. IACA solo requiere la capacidad de leer el binario para ser analizado. Por lo tanto, es posible, usando IACA, analizar un binario Haswell empleando instrucciones FMA en una máquina Pentium III.

C / C++

En C y C++, se obtiene acceso a macros de inyección de marcadores con #include "iacaMarks.h", donde iacaMarks.h es un encabezado que se envía con la herramienta en el subdirectorio include/.

Luego se insertan los marcadores alrededor del interior bucle de interés, o el trozo de interés en línea recta, de la siguiente manera:

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

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

La aplicación se reconstruye como lo haría de otra manera con las optimizaciones habilitadas (En modo Release para usuarios de IDE como Visual Studio). La salida es un binario que es idéntico en todos los aspectos a la compilación de la versión excepto con la presencia de las marcas, que hacen que la aplicación no sea ejecutable.

IACA se basa en que el compilador no reordene las marcas en exceso; como tal, para tales compilaciones de análisis ciertas optimizaciones potentes pueden necesitar ser deshabilitadas si reordenan las marcas para incluir código extraño que no esté dentro del bucle más interno, o excluir código dentro de él.

Asamblea (x86)

Los marcadores de IACA son patrones de bytes mágicos inyectados en la ubicación correcta dentro del código. Cuando se usa iacaMarks.h en C o C++, el compilador se encarga de insertar los bytes mágicos especificados por el encabezado en la ubicación correcta. En assembly, sin embargo, debe insertar manualmente estas marcas. Por lo tanto, uno debe haga lo siguiente:

    ; 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

Es crítico para los programadores de C/C++ que el compilador logre este mismo patrón.

Lo que produce:

Como ejemplo, analicemos el siguiente ejemplo de ensamblador en la arquitectura de 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

Añadimos inmediatamente antes de la etiqueta .L2 el marcador inicial e inmediatamente después de jne el marcador final. Luego reconstruimos el software, e invocamos IACA de esta manera (En Linux, asume que el directorio bin/ está en el path, y foo para ser un objeto ELF64 que contiene las marcas IACA):

iaca.sh -64 -arch HSW -graph insndeps.dot foo

, produciendo así un informe de análisis del binario de 64 bits foo cuando se ejecuta en un procesador Haswell, y un gráfico de las dependencias de instrucción visibles con Graphviz.

El informe se imprime en la salida estándar (aunque puede ser dirigido a un archivo con un conmutador -o). El informe dado para el fragmento anterior es:

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

La herramienta ayuda a señalar que actualmente, el cuello de botella es el Interfaz Haswell y AGU de los puertos 2 y 3. Este ejemplo nos permite diagnosticar el problema como la tienda no está siendo procesada por el puerto 7, y tomar medidas correctivas.

Limitaciones:

IACA no soporta unas pocas instrucciones, que son ignoradas en el análisis. No admite procesadores más antiguos que Nehalem y no admite bucles no internos en modo de rendimiento (no tiene la capacidad de adivinar qué rama se toma con qué frecuencia y en qué patrón).

 62
Author: Iwillnotexist Idonotexist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-03 09:04:48