NEON,SSE和交错负载与shuffle

时间:2016-05-09 01:03:43

标签: arm x86-64 sse neon

我试图理解“{Iwillnotexist Idonotexist”在SIMD optimization of cvtColor using ARM NEON intrinsics发表的评论:

  

...为什么不使用映射到VLD3指令的ARM NEON内在函数?这样可以避免所有的混乱,简化和加速代码。英特尔SSE实现需要随机播放,因为它缺少2/3/4路去交错加载指令,但是当它们可用时你不应该传递它们。

我遇到的麻烦是解决方案提供了非交错的代码,并且它在浮点上执行融合乘法。我试图将两者分开,只了解交错负载。

根据另一个问题的评论和Coding for NEON - Part 1: Load and Stores,答案可能会使用VLD3

不幸的是,我只是没有看到它(可能是因为我对NEON及其内在功能不太熟悉)。似乎VLD3基本上为每个输入产生3个输出,所以我的金属模型很混乱。

鉴于以下SSE instrinsics对BGR BGR BGR BGR...格式的数据进行操作,需要对BBBB GGGG RRRR ...进行随机播放:

const byte* data = ...  // assume 16-byte aligned
const __m128i mask = _mm_setr_epi8(0,3,6,9,12,15,1,4,7,10,13,2,5,8,11,14);
__m128i a = _mm_shuffle_epi8(_mm_load_si128((__m128i*)(data)),mask);

我们如何使用NEON内在函数执行交错负载,以便我们不需要SSE shuffle?

另请注意......我对内在函数感兴趣,而不是ASM。我可以在MSVC,ICC,Clang等的Windows Phone,Windows Store和Linux驱动的设备上使用ARM的内在函数。我不能用ASM做到这一点,我不是要尝试专门化代码3次(Microsoft 32-位ASM,Microsoft 64位ASM和GCC ASM)。

1 个答案:

答案 0 :(得分:1)

根据这个页面:

您需要的VLD3内在是:

int8x8x3_t  vld3_s8(__transfersize(24) int8_t const * ptr);
// VLD3.8 {d0, d1, d2}, [r0]

如果在ptr指向的地址处有此数据:

0x00: 33221100
0x04: 77665544
0x08: bbaa9988
0x0c: ffddccbb
0x10: 76543210
0x14: fedcba98

你最终会进入寄存器:

d0: ba54ffbb99663300
d1: dc7610ccaa774411
d2: fe9832ddbb885522

int8x8x3_t结构定义为:

struct int8x8x3_t
{
   int8x8_t val[3];
};