为什么在实践中向右移位会在霓虹灯和SSE中向左移位(反之亦然)?

Ant*_*nio 0 c++ sse shift intrinsics neon

(注意,在Neon我使用这种数据类型以避免处理16位数据类型之间的转换)

为什么实践中"内移"中的"左移"是"向右移"?

// Values contained in a
// 141 138 145 147 144 140 147 153 154 147 149 146 155 152 147 152
b = vshlq_n_u32(a,8);
// Values contained in b
// 0 141 138 145 0 144 140 147 0 154 147 149 0 155 152 147
b = vshrq_n_u32(a,8);
// Values contained in b
// 138 145 147 0 140 147 153 0 147 149 146 0 152 147 152 0
Run Code Online (Sandbox Code Playgroud)

我记得在使用时会发现相同的情况_mm_slli_si128(虽然不同但是换班后的结果如下所示:

// b = _mm_slli_si128(a,1);
// 0 141 138 145 147 144 140 147 153 154 147 149 146 155 152 147
Run Code Online (Sandbox Code Playgroud)

是因为字节序吗?它会从平台变为平台吗?

kfs*_*one 5

你说"这是因为结束",但更多的是类型滥用.您正在假设跨越字节/字边界的机器的位排序以及对操作施加局部字节顺序的非字节指令(您使用的是_u32指令,该指令期望值是无符号的32位值,而不是数组8位值).

正如你所说,你要求它通过/ ask/it来移动一系列无符号字符值,以32位为单位移位值.

遗憾的是,如果您希望能够对它们进行架构转换,则需要将它们置于架构顺序中.

否则,您可能希望查找blit或移动指令,但是您无法在不支付架构成本的情况下人为地将机器类型强制转换为机器寄存器.字节序只是你的头痛之一(对齐,填充等)

---晚编辑---

从根本上说,你是混淆字节和位移,我们认为最重要的位是"左"

bit number
87654321

hex
8421
00008421

00000001  = 0x01 (small, less significant)
10000000  = 0x80 (large, more significant)
Run Code Online (Sandbox Code Playgroud)

但是你要移位的值是32位字,在一个小端机器上,这意味着每个后续地址增加了一个32位字的值的更重要的字节:

bit numbers
                1111111111111111
87654321fedcba0987654321fedcba09
Run Code Online (Sandbox Code Playgroud)

表示32位值0x0001

                1111111111111111
87654321fedcba0987654321fedcba09

00000001000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

将其左移2个位置

00000001000000000000000000000000
     v<
00000100000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

将它转移到另外8个位置,我们必须将它转到下一个地址:

00000100000000000000000000000000
      >>>>>>>v
00000000000001000000000000000000
Run Code Online (Sandbox Code Playgroud)

如果您以字节为单位思考,这看起来像是一个正确的转变.但我们告诉这个小端CPU我们正在使用uint32,这意味着:

                1111111111111111
87654321fedcba0987654321fedcba09
 word01  word02  word03  word04   
00000001000000000000000000000000 = 0x0001
00000100000000000000000000000000 = 0x0004
00000000000001000000000000000000 = 0x0400
Run Code Online (Sandbox Code Playgroud)

问题是,这是一个不同于您对8位值本地数组所期望的排序的顺序,但是您告诉CPU值为_u32,因此它使用了它的本机endianess来进行操作.