【发布时间】:2016-05-28 18:34:30
【问题描述】:
我们在 Debug 构建下触发了一个断言来检查对齐。断言适用于使用vld1q_u8 加载到uint8x16_t 中的字节数组。当断言触发时,我们没有观察到SIG_BUS。
代码中的用法如下:
const byte* input = ...;
...
assert(IsAlignedOn(input, GetAlignmentOf(uint8x16_t));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
我也尝试了以下方法,断言触发uint8_t* 的对齐:
assert(IsAlignedOn(input, GetAlignmentOf(uint8_t*));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
将字节数组加载到带有vld1q_u8 的uint8x16_t 时,其对齐要求是什么?
在上面的代码中,input 是一个函数参数。 IsAlignedOn 检查其两个参数的对齐方式,确保第一个参数至少与第二个参数对齐。 GetAlignmentOf 是一种抽象,用于检索类型或变量的对齐方式。
uint8x16_t 和 uint64x2_t 是 128 位 ARM NEON 矢量数据类型,它们是 expected to be placed in a Q register。 vld1q_u8 是一个 NEON 伪指令,预计将被编译成 VLD1.8 指令。 vreinterpretq_u64_u8 是一个 NEON 伪指令,可简化数据类型的使用。
【问题讨论】:
-
代码不是C。
-
@Olaf - 我不确定你是否正确。它们是内在函数,which are a C language extension。引用的 GCC 文档指的是 ARM 文档,因此如果您想阅读它们,您应该同时拥有这两个参考。
-
@Olaf - 我们的源代码用于构建多个平台和多个编译器。编译器包括 GCC、Clang、MSVC。这些平台包括 Linux、Windows Phone 和 Windows Store。
GetAlignmentOf只是一个抽象。 (很多人没有意识到 Microsoft 编译器使用 ARM 内部函数)。 -
这几乎完全是特定于编译器的,因为它完全取决于它们如何实现内部类型以及是否要将对齐提示添加到底层指令中。据我所见,即使保证对齐,GCC也不会发出提示; Clang 倾向于尽可能地这样做。不知道MSVC。至于它们中的任何一个是否正确实现了向量类型,或者只是将它们类型定义为
struct {long long[2]}(导致对齐过于严格),我从来没有看过。 -
我已经给你提示了。没必要粗鲁。
_Alignas等是标准 C。只需使用现代编译器,它不会被 27 年前的标准版本卡住。
标签: arm memory-alignment neon intrinsics