为什么 VPMOVMSKB 似乎产生了不正确的结果?
Why does VPMOVMSKB appear to produce incorrect results?
根据 Intel 文档,vpmovmskb
可以:
Instruction: vpmovmskb r32, ymm
Create mask from the most significant bit of each 8-bit element in a, and store the result in dst.
根据 GDB,我在 %ymm0
寄存器中有一个具有此值的向量:
v32_int8 = {0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0}
.
在我跨过指令 vpmovmskb %ymm0,%eax
之后,我希望得到一个 4 字节的位掩码,如下所示:0b00100000'10000010'00001000'00100000
。但是根据 GDB,我在 %eax
中实际得到的是 0b00000100'00010000'01000001'00000100
。我对此很困惑。看起来我期望的结果位移了 3,但我不知道为什么。
这里有人知道我可能遗漏了什么吗?我是否误解了正确的行为?
您观察到的不直观,但没有任何错误。 Visual Studio 调试器打印出同样的东西:
eax,b 0b00000100000100000100000100000100 unsigned int
当调试器打印 SIMD 向量时,它们会像存储在内存中一样打印它们。这意味着第一个通道在调试器的左侧。 Visual Studio 调试器是一个 GUI 应用程序,它显示可扩展数组,第一个元素在顶部,它还在元素附近显示从 0 开始的索引。
然而,当打印单个数字时,最低有效位在右边,最高有效位在左边。因此,当您查看以二进制形式打印的 uint32_t
数字时,您应该记住位顺序在那里是相反的:第一个位 #0 在字符串的右侧,最后一个位 #31 在字符串的左侧字符串。
在您的 AVX 向量中,设置高位的第一个字节位于通道 #2(假设 zero-based 编号),第二个字节位于通道 #8。如果您查看二进制结果,您会注意到右侧的位#2 和#8 设置为该数字。
根据 Intel 文档,vpmovmskb
可以:
Instruction: vpmovmskb r32, ymm
Create mask from the most significant bit of each 8-bit element in a, and store the result in dst.
根据 GDB,我在 %ymm0
寄存器中有一个具有此值的向量:
v32_int8 = {0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0}
.
在我跨过指令 vpmovmskb %ymm0,%eax
之后,我希望得到一个 4 字节的位掩码,如下所示:0b00100000'10000010'00001000'00100000
。但是根据 GDB,我在 %eax
中实际得到的是 0b00000100'00010000'01000001'00000100
。我对此很困惑。看起来我期望的结果位移了 3,但我不知道为什么。
这里有人知道我可能遗漏了什么吗?我是否误解了正确的行为?
您观察到的不直观,但没有任何错误。 Visual Studio 调试器打印出同样的东西:
eax,b 0b00000100000100000100000100000100 unsigned int
当调试器打印 SIMD 向量时,它们会像存储在内存中一样打印它们。这意味着第一个通道在调试器的左侧。 Visual Studio 调试器是一个 GUI 应用程序,它显示可扩展数组,第一个元素在顶部,它还在元素附近显示从 0 开始的索引。
然而,当打印单个数字时,最低有效位在右边,最高有效位在左边。因此,当您查看以二进制形式打印的 uint32_t
数字时,您应该记住位顺序在那里是相反的:第一个位 #0 在字符串的右侧,最后一个位 #31 在字符串的左侧字符串。
在您的 AVX 向量中,设置高位的第一个字节位于通道 #2(假设 zero-based 编号),第二个字节位于通道 #8。如果您查看二进制结果,您会注意到右侧的位#2 和#8 设置为该数字。