6

我想通过 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 兼容的工具?

4

1 回答 1

8

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
于 2019-05-16T11:30:15.647 回答