发布于 2016-07-01 16:31:11
TL;DR:使用本质
检查asm输出以确保它不是哑的并不是个坏主意,但是使用intrinsics可以让编译器进行常量传播,并对顺序内核进行调度/软件管道。
如果您阅读从2009年起你联系的那个帖子上的注释线程,您会发现来自NEON的坏代码是一个gcc错误修复于2011年。
编译器现在非常擅长处理内部的问题,并且不断改进。尤其是Clang可以做很多事情,比如使用不同的洗牌指令,而不是用本质写的东西。
至少它们适用于x86;用于ARM的编译器有时仍在与本质进行斗争,特别是当您试图访问16字节向量的两个8字节部分时,就像您通常希望在32位ARM代码中进行横向操作时那样。参见https://stackoverflow.com/questions/46910799/arm-neon-intrinsics-convert-d-64-bit-register-to-low-half-of-q-128-bit-regis / https://stackoverflow.com/questions/49511244/neon-intrinsic-for-sum-of-two-subparts-of-a-q-register -杰克·李报道说,早在2018年,一些clang版本就把它搞得一团糟,但GCC6.x并没有那么糟糕。
这在AArch64中可能没有那么大的问题。
asm-级别差异:
我根本不是这方面的专家,但主要的霓虹灯变化之一是,Aarch64有32个128 B霓虹灯寄存器(v0 - v31),而不是每个q寄存器混叠成两个d半。
还请参阅一些关于元素大小语法的官方ARM文件,其中可以使用.16B来指示由16个字节元素组成的向量。(相对于意味着每个元素是8位。)
https://stackoverflow.com/questions/38149695
复制相似问题