【发布时间】:2015-12-29 10:52:03
【问题描述】:
我使用英特尔编译器编译了一段带有选项 -xSSE4.1 的代码。当我查看生成的程序集文件时,我看到已经插入了诸如“vpmovzxbw”之类的 AVX 指令。但是,可执行文件似乎仍然可以在不支持 AVX 指令集的机器上运行。这是什么原因?
这是特定的代码 sn-p -
C -> src0_8x16b = _mm_cvtepu8_epi16 (src0_8x16b);
Assembly -> vpmovzxbw xmm4, QWORD PTR [rcx]
Binary -> 00066 c4 62 79 30 29
这是另一个 sn-p,其中汇编指令使用 3 个操作数 -
C -> src0_8x16b = _mm_sub_epi16 (src0_8x16b, src1_8x16b);
Assembly -> vpsubw xmm1, xmm13, xmm11
Binary -> 000bc c4 c1 11 f9 cb
为了比较,这里是 icc 为函数 'foo' 生成的反汇编(函数 foo 和上面的代码 sn-p 的唯一区别是代码 sn-p 是使用内在函数编码的) em> -
Compiler commands used -
icc -S -xSSE4.1 -axavx -O3 foo.c
Function foo -
void foo(float *x, int n)
{
int i;
for(i=0; i<n; i++) x[i] *= 2.0;
}
Autodispatch code -
testl $-131072, __intel_cpu_indicator(%rip) #1.27
jne foo.R #1.27
testl $-1, __intel_cpu_indicator(%rip) #1.27
jne foo.A
Loop in foo.R (AVX variant) -
vmulps (%rdi,%rcx,4), %ymm0, %ymm1 #3.24
vmulps 32(%rdi,%rcx,4), %ymm0, %ymm2 #3.24
vmovups %ymm1, (%rdi,%rcx,4) #3.24
vmovups %ymm2, 32(%rdi,%rcx,4) #3.24
addq $16, %rcx #3.5
cmpq %rdx, %rcx #3.5
jb ..B2.12 # Prob 82% #3.5
Loop in foo.A (SSE variant) -
movaps (%rdi,%r8,4), %xmm1 #3.24
movaps 16(%rdi,%r8,4), %xmm2 #3.24
mulps %xmm0, %xmm1 #3.24
mulps %xmm0, %xmm2 #3.24
movaps %xmm1, (%rdi,%r8,4) #3.24
movaps %xmm2, 16(%rdi,%r8,4) #3.24
addq $8, %r8 #3.5
cmpq %rsi, %r8 #3.5
jb ..B3.12 # Prob 82% #3.5
【问题讨论】:
-
felixcloutier.com/x86/PMOVZX.html你可能和VPMOVZXBW混淆了
-
pmovzx 是 sse41。 vpmovzxbw 是 avx。检查link
-
也许它会生成一些东西的 AVX 版本,但只有在运行时检查系统支持 AVX 后才会运行它?发布一个反汇编的片段,包括二进制机器代码,这样我们就可以确保它真的是 VEX 编码。理想情况下,如果您在 AVX 之前的机器上有调试器,请在该指令处设置断点并确保它也确实运行过。
-
能否请您显示您的代码、编译器选项、编译器版本和生成的程序集。
-
ICC根据Agner Fog生成一个CPU调度器。他对此进行了很多详细说明。我不知道它是如何工作的。我认为它适用于库而不是您自己的代码。但我过去在 ICC 的经验是 trouble getting ICC to generated the code I told it to。