为什么 VPMOVMSKB 似乎产生了不正确的结果?

EPonyA

根据英特尔文档,vpmovmskb确实:

指令:vpmovmskb r32, ymm

从 a 中每个 8 位元素的最高有效位创建掩码,并将结果存储在 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 字节的位掩码,如下所示: 0b 00100000'10000010'00001000'00100000%eax但根据 GDB,我实际上得到的是 0b 00000100'00010000'01000001'00000100我对此感到非常困惑。看起来我期望的结果被位移了 3,但我不知道为什么。

这里有人知道我可能会错过什么吗?我误解了正确的行为吗?

松子

您观察到的内容并不直观,但任何地方都没有错误。Visual Studio 调试器打印同样的事情:

eax,b   0b00000100000100000100000100000100  unsigned int

当调试器打印 SIMD 向量时,它们会像存储在内存中一样打印它们。这意味着第一个通道在调试器的左侧。Visual Studio 调试器是一个 GUI 应用程序,它显示可扩展数组,第一个元素位于顶部,并且它还在元素附近显示从 0 开始的索引。

但是,当打印单个数字时,最低有效位在右侧,最高有效位在左侧。因此,当您查看以uint32_t二进制形式打印的数字时,您应该记住位顺序是颠倒的:第一位 #0 在字符串的右侧,最后一位 #31 在字符串的左侧。

在您的 AVX 向量中,设置了高位的第一个字节位于通道 #2(假设从零开始编号),第二个字节位于通道 #8。如果您查看二进制结果,您会注意到右侧的第 2 位和第 8 位设置在该数字中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章