英特尔 IACA 分析器改变装配体?
Intel IACA analyzer alters assembly?
我想通过 IACA 分析器 运行 一些代码来查看它使用了多少 uops -- 我从一个简单的函数开始看它是否工作..
不幸的是,当我插入 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 兼容的工具?
IACA 标记宏只是内联 asm(或对于 64 位 MSVC:start = __writegsbyte(111, 111);
和 stop = 222
)。它们可能会干扰优化器,或最终出现在错误的位置(例如,不是陷入循环之前的最后一条指令,因此该块包含一些循环设置)。
如果发生这种情况,就像您的情况一样,最好的办法是要求编译器生成 asm(而非机器代码)输出,然后 手动将标记插入您要分析的 asm。
在 NASM 语法中,我使用此 %if
/ %else
块,因此我可以使用 nasm -DIACA_MARKS
构建或不构建。我知道这不是 MASM 的正确语法,但 IACA start/end 标记非常简单: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
我想通过 IACA 分析器 运行 一些代码来查看它使用了多少 uops -- 我从一个简单的函数开始看它是否工作..
不幸的是,当我插入 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 兼容的工具?
IACA 标记宏只是内联 asm(或对于 64 位 MSVC:start = __writegsbyte(111, 111);
和 stop = 222
)。它们可能会干扰优化器,或最终出现在错误的位置(例如,不是陷入循环之前的最后一条指令,因此该块包含一些循环设置)。
如果发生这种情况,就像您的情况一样,最好的办法是要求编译器生成 asm(而非机器代码)输出,然后 手动将标记插入您要分析的 asm。
在 NASM 语法中,我使用此 %if
/ %else
块,因此我可以使用 nasm -DIACA_MARKS
构建或不构建。我知道这不是 MASM 的正确语法,但 IACA start/end 标记非常简单: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