【发布时间】:2014-05-13 14:03:34
【问题描述】:
我想知道您是否可以帮助我使用 NEON 内在函数来优化此遮罩功能。我已经尝试使用 O3 gcc 编译器标志使用自动矢量化,但该函数的性能比使用 O2 运行它要小,O2 会关闭自动矢量化。由于某种原因,使用 O3 生成的汇编代码比使用 O2 生成的汇编代码长 1.5。
void mask(unsigned int x, unsigned int y, uint32_t *s, uint32_t *m)
{
unsigned int ixy;
ixy = xsize * ysize;
while (ixy--)
*(s++) &= *(m++);
}
可能我必须使用以下命令:
vld1q_u32 // 从 s 和 m 加载 4 个整数
vandq_u32 // 在 s 和 m 的 4 个整数之间执行逻辑和
vst1q_u32 // 将它们存储回 s
但是我不知道如何以最佳方式做到这一点。例如,我应该在加载、和存储之后将 s,m 增加 4 吗?我对 NEON 很陌生,所以我真的需要一些帮助。
我正在使用 gcc 4.8.1,并且正在使用以下 cmd 进行编译:
arm-linux-gnueabihf-gcc -mthumb -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -O3 -fprefetch-loop-数组名称.c -o 名称
提前致谢
【问题讨论】:
-
我可以为您提供以下建议:使用 -fno-tree-vectorize 关闭自动矢量化。并且远离内在函数,除非你想花更多的时间调试而不是编码。如果您需要 NEON 来满足您的目的,请进行组装。
-
感谢您的回复。所以你建议在汇编中编写函数比内在函数更有效?我认为内在函数映射到特定的汇编指令,因此它与编写汇编非常相似。内在函数会导致什么样的问题???
-
自从 Linaro 接管了 GCC,它比以前更好,因为 Intrinsics 生成的代码简直就是垃圾。现在,在处理简单示例时,您可能会通过内在函数获得不错的性能。然而,当涉及到需要大量寄存器的实际现场使用时,尤其是当它们被置换时,内在函数会做很多模糊的事情,比如在寄存器之间不必要地传输数据。