Я нашел этот интересный и мощный инструмент под названием IACA (анализатор кода архитектуры Intel), но мне трудно это понять. Что я могу с этим сделать, каковы его ограничения и как я могу:
2017-11Версия 3.0 вышел (последнее по состоянию на 2017-11-03)
2017-03Версия 2,3 вышел
IACA (анализатор кода архитектуры Intel) это бесплатный инструмент статического анализа с закрытыми исходными кодами, разработанный Intel для статического анализа планирования команд при выполнении современными процессорами Intel. Это позволяет ему вычислять для данного фрагмента,
при предположении оптимальных условий выполнения (все обращения к памяти попадают в кэш L1, и нет ошибок страницы).
IACA поддерживает вычисления для процессоров Nehalem, Westmere, Sandy Bridge, Ivy Bridge, Haswell, Broadwell и Skylake начиная с версии 2.3 и Haswell, Broadwell и Skylake начиная с версии 3.0.
IACA — это инструмент командной строки, который создает текстовые отчеты ASCII и диаграммы Graphviz. Версии 2.1 и ниже поддерживают 32- и 64-разрядные версии Linux, Mac OS X и Windows, а также анализ 32-разрядного и 64-разрядного кода; Версия 2.2 и выше поддерживает только 64-битные ОС и анализ 64-битного кода.
Ввод IACA — это скомпилированный двоичный код вашего кода, в который были вставлены два маркеры: маркер начала и маркер конца. Маркеры делают код недоступным для выполнения, но позволяют инструменту быстро находить соответствующие фрагменты кода и анализировать их.
Вам не нужна возможность запуска двоичного файла в вашей системе; На самом деле, бинарный файл поставляется в IACA не может запустить в любом случае из-за присутствия введенных маркеров в коде. IACA требует только умения читать двоичный файл для анализа. Таким образом, с помощью IACA можно анализировать двоичный файл Haswell с использованием инструкций FMA на компьютере с процессором Pentium III.
В 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). Вывод представляет собой двоичный файл, который идентичен во всех отношениях сборке Release, за исключением наличия меток, которые делают приложение неработоспособным.
IACA полагается на то, что компилятор не слишком переупорядочивает метки; Таким образом, для таких сборок анализа может потребоваться отключение определенных мощных оптимизаций, если они переупорядочивают метки для включения постороннего кода, не входящего в самый внутренний цикл, или исключая код внутри него.
Маркеры IACA — это шаблоны магических байтов, введенные в правильном месте в коде. Когда используешь iacaMarks.h
в C или C ++ компилятор обрабатывает вставку магических байтов, указанных в заголовке в правильном месте. В сборке, однако, вы должны вручную вставить эти метки. Таким образом, нужно сделать следующее:
; 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
Мы добавляем непосредственно перед .L2
обозначить стартовый маркер и сразу после jne
маркер конца. Затем мы перестраиваем программное обеспечение и вызываем IACA таким образом (в Linux предполагается, что bin/
каталог, который будет в пути, и foo
быть объектом ELF64, содержащим метки IACA):
iaca.sh -64 -arch HSW -graph insndeps.dot foo
, таким образом производя отчет анализа 64-битного двоичного файла foo
при запуске на процессоре Haswell и графике зависимостей команд, доступных для просмотра с помощью 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 и AGU портов 2 и 3. Этот пример позволяет нам диагностировать проблему как хранилище, которое не обрабатывается портом 7, и принять меры по исправлению.
IACA не поддерживает несколько инструкций, которые игнорируются при анализе. Он не поддерживает процессоры, более старые, чем Nehalem, и не поддерживает не внутренние циклы в режиме пропускной способности (не имея возможности угадать, какая ветвь берется, как часто и по какой схеме).