Intel IACA анализатор изменяет сборку? - PullRequest
6 голосов
/ 16 мая 2019

Я хотел запустить какой-то код через анализатор IACA, чтобы увидеть, сколько мопов он использовал - я начал с простой функции, чтобы посмотреть, работает ли он ...

К сожалению, когда я вставляю макросы, которые, по словам IACA, используются, результирующая сборка сильно отличалась, и поэтому ее анализ бесполезен.

Вот сборка, произведенная без IACA

00007FF9CD590580  vaddps      ymm1,ymm5,ymmword ptr [rax]  
00007FF9CD590584  vaddps      ymm2,ymm6,ymmword ptr [rax+20h]  
00007FF9CD590589  vaddps      ymm3,ymm7,ymmword ptr [rax+40h]  
00007FF9CD59058E  vmulps      ymm4,ymm1,ymm1  
00007FF9CD590592  vfmadd231ps ymm4,ymm2,ymm2  
00007FF9CD590597  vfmadd231ps ymm4,ymm3,ymm3  
00007FF9CD59059C  vcmpgt_oqps ymm1,ymm4,ymm9  
00007FF9CD5905A2  vrsqrtps    ymm0,ymm4  
00007FF9CD5905A6  vandps      ymm2,ymm1,ymm0  
00007FF9CD5905AA  vmovups     ymm3,ymm8  
00007FF9CD5905AF  vfmsub231ps ymm3,ymm2,ymm4  
00007FF9CD5905B4  vmovups     ymmword ptr [r9+rax],ymm3  
00007FF9CD5905BA  add         rax,rcx  
00007FF9CD5905BD  sub         r8d,1  
00007FF9CD5905C1  jne         fm::EvlOp::applyLoop<`RegisterShapeOps<fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> > >'::`2'::doDISTANCE_SPHERE_11,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::DataWrapper,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::RegisterBlock,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::instruction_input>+0B0h (07FF9CD590580h)  

И вот что он выдает, когда я добавляю макросы IACA ... (я тестирую двоичный файл MSVC, поэтому я использую IACA_VC64_START и IACA_VC64_END, как указано в руководстве).

00007FF9CD59058B  vmovups     ymm2,ymmword ptr [rax+40h]  
00007FF9CD590590  vmovups     ymm0,ymmword ptr [rax]  
00007FF9CD590594  vmovups     ymm1,ymmword ptr [rax+20h]  
00007FF9CD590599  vaddps      ymm3,ymm2,ymm8  
00007FF9CD59059E  vmovups     ymmword ptr [rbp+20h],ymm0  
00007FF9CD5905A3  vaddps      ymm0,ymm0,ymm6  
00007FF9CD5905A7  vmovups     ymmword ptr [rbp+40h],ymm1  
00007FF9CD5905AC  vmulps      ymm4,ymm0,ymm0  
00007FF9CD5905B0  vaddps      ymm1,ymm1,ymm7  
00007FF9CD5905B4  vfmadd231ps ymm4,ymm1,ymm1  
00007FF9CD5905B9  vfmadd231ps ymm4,ymm3,ymm3  
00007FF9CD5905BE  vcmpgt_oqps ymm1,ymm4,ymm5  
00007FF9CD5905C3  vrsqrtps    ymm0,ymm4  
00007FF9CD5905C7  vmovups     ymmword ptr [rbp+60h],ymm2  
00007FF9CD5905CC  vandps      ymm2,ymm1,ymm0  
00007FF9CD5905D0  vmovups     ymm3,ymm9  
00007FF9CD5905D5  vfmsub231ps ymm3,ymm2,ymm4  
00007FF9CD5905DA  vmovups     ymmword ptr [rcx+rax],ymm3  
00007FF9CD5905DF  add         rax,rdx  
00007FF9CD5905E2  mov         qword ptr [rbp+18h],rax  
00007FF9CD5905E6  vmovups     ymmword ptr [rbp+80h],ymm3  
00007FF9CD5905EE  sub         r8d,1  
00007FF9CD5905F2  jne         fm::EvlOp::applyLoop<`RegisterShapeOps<fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> > >'::`2'::doDISTANCE_SPHERE_11,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::DataWrapper,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::RegisterBlock,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::instruction_input>+0B2h (07FF9CD590582h)  

Итак, он вставил много ходов, и теперь мой (надеюсь) слитый адд больше не слит - -

Я надеялся, что он сможет сказать мне, если

00007FF9CD590584  vaddps      ymm2,ymm6,ymmword ptr [rax+20h] 

Оставался слитным, но он удалил этот код все вместе ..

Это известная проблема, или, может быть, из-за того, что я использую MSVC, что может быть не очень распространено?

Возможно, есть способ это исправить или лучший инструмент, совместимый с MSVC?

1 Ответ

8 голосов
/ 16 мая 2019

Макросы метки IACA являются просто встроенными asm (или для 64-битного MSVC: start = __writegsbyte(111, 111); и stop = 222).Они могут потенциально помешать оптимизатору или оказаться в неправильном месте (например, не последняя инструкция перед попаданием в цикл, поэтому блок включает некоторую настройку цикла).

Если это произойдет, как в вашем случае,Лучше всего попросить компилятор произвести вывод asm (не машинного кода), и вручную вставить маркеры в asm, который вы хотите проанализировать.


В синтаксисе NASM:Я использую этот блок %if / %else, поэтому могу строить с nasm -DIACA_MARKS или нет.Я знаю, что это неправильный синтаксис для MASM, но маркеры начала / конца IACA довольно просты: mov до EBX и fs addr32 nop.

%ifdef IACA_MARKS

%macro  IACA_start 0             ; NASM macro with 0 args, defines IACA_start
     mov ebx, 111
     db 0x64, 0x67, 0x90
%endmacro
%macro  IACA_end 0
     mov ebx, 222
     db 0x64, 0x67, 0x90
%endmacro

%else
%define IACA_start
%define IACA_end
%endif
...