这是简单的二值化函数
void binarize(void *output, const void *input, int begin, int end, uint8_t threshold) {
#ifdef __ARM_NEON__
uint8x16_t thresholdVector = vdupq_n_u8(threshold);
uint8x16_t highValueVector = vdupq_n_u8(255);
uint8x16_t* __restrict inputVector = (uint8x16_t*)input;
uint8x16_t* __restrict outputVector = (uint8x16_t*)output;
for ( ; begin < end; begin += 16, ++inputVector, ++outputVector) {
*outputVector = (*inputVector > thresholdVector) & highValueVector;
}
#endif
}
它在 iOS 上运行良好。然而,当我为 Android 编译它时,它给了我一个错误:
error: invalid operands of types 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' and 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' to binary 'operator>'
我在 Android.mk 中使用此标志来启用 NEON:
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_ARM_NEON := true
endif
最佳答案
差异是由于不同的编译器造成的。对于 iOS,您使用 Clang 进行编译,但对于 Android,您使用 GCC 构建代码(除非您覆盖默认值)。
GCC 对向量类型的处理要愚蠢得多,无法将它们与 C/C++ 运算符(如 >
或 &
一起使用)。所以你有两个基本选择:
尝试从最新的 Android NDK r8c 中使用 Clang 进行编译
将
NDK_TOOLCHAIN_VERSION=clang3.1
放入您的Application.mk
中。- 显式重写代码,使用
vld1q_u8
进行加载,使用vst1q_u8
进行存储,vcgtq_u8
进行operator >
和vandq_u8
用于运算符&
关于android - 在 Android 上编译 NEON 代码时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13776228/