jww*_*jww 2 arm memory-alignment intrinsics neon
我们在调试构建下触发了一个断言来检查对齐情况。断言适用于加载到 using 中的字节uint8x16_t数组vld1q_u8。当断言触发时,我们没有观察到SIG_BUS.
下面是代码中的使用:
const byte* input = ...;
...
assert(IsAlignedOn(input, GetAlignmentOf(uint8x16_t));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
Run Code Online (Sandbox Code Playgroud)
我还尝试了以下操作,并触发断言以进行对齐uint8_t*:
assert(IsAlignedOn(input, GetAlignmentOf(uint8_t*));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
Run Code Online (Sandbox Code Playgroud)
将字节数组加载到 with 时有哪些对齐uint8x16_t要求vld1q_u8?
上面的代码中,input是一个函数参数。IsAlignedOn检查其两个参数的对齐方式,确保第一个参数至少与第二个参数对齐。GetAlignmentOf是检索类型或变量的对齐方式的抽象。
uint8x16_t和uint64x2_t是 128 位 ARM NEON 向量数据类型,预计放置在 Q 寄存器中。vld1q_u8是一个 NEON 伪指令,预计会被编译成VLD1.8指令。vreinterpretq_u64_u8是一条 NEON 伪指令,可简化数据类型的使用。
当编写直接汇编程序(内联或外部文件)时,您可以选择是否要指定对齐方式(例如vld1.8 {q0}, [r0, :64])或将其省略(例如vld1.8 {q0}, [r0])。如果没有指定,则根本不需要任何特定的对齐,如 Dric512 所说。
当使用vld1q_u8via内在函数时,您实际上并不指定对齐方式,因此据我所知,编译器不会假设它,并生成没有对齐规范的指令。我不确定某些编译器是否可以推断出一些实际上保证对齐的情况,并在这些情况下使用对齐说明符。(在这种特殊情况下,gcc、clang 和 MSVC 似乎都在没有对齐说明符的情况下生成vld1.8。)
请注意,这只是 32 位 ARM 上的问题;在 AArch64 中,指令没有对齐说明符ld1。但即使如此,对齐显然仍然有帮助,如果将其与未对齐的地址一起使用,性能会更差。