如何在 ARM NEON SIMD 内在函数上编写“a[i]=b[c[i]]”

Posted

技术标签:

【中文标题】如何在 ARM NEON SIMD 内在函数上编写“a[i]=b[c[i]]”【英文标题】:How to code "a[i]=b[c[i]]" on ARM NEON SIMD Intrinsic function 【发布时间】:2017-06-04 10:55:39 【问题描述】:

我正在尝试将此 C/C++ 代码转换为 SIMD 内在函数。

for(int i=0 ; i < length ; i++)
    A[i] = B[C[i]];

我可以翻译下面的代码(C/C++)

for(int i=0 ; i < length ; i++)
    A[i] = B[i];

到 SIMD 代码(使用内部函数)

for(int i=0 ; i < length-16 ; i+=16) 
    uint8x16_t v0 = vld1q_u8(A+i);
    vst1q_u8(A+i, v0);

我知道关键字交错来解决这个问题。但我找不到解决方案。

谢谢。

编辑For more information

unsigned char A [32] = 0,; // Output Array
unsigned char B [20] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20; // An array with values to pass to A Array
unsigned int C [32] = 19,15,11,10,5,3,6,4,5,19,10,14,16,14,8,9,10,20,11,1, 0, 3, 5, 19, 20, 11, 13, 9, 30, 31, 7; // An array with the index information of the B array.

有没有Intrinsic函数可以做成如下代码形式?

int length = 32;
For (int i = 0; i < length-8; i+=8)

    Uint8x8_t v_idx = vld1_u8 (C + i);
    Uint8x8_t v = func (A, v_idx); // func (uint8_t, uint32x4_t)
    vst1_u8(C+i, v);

将输出20, 16, 12, 11, 6, 4, 7, 5, 6, 6, 20, 11, 15, 17, 15, 9, 10, 11, 21, 12, 2, 1, 4, 6, 20, 21, 12, 14, 10, 31, 32, 8

[注意] A 和 B 是 uint8_t * 类型,因为它们是值介于 0 和 255 之间的图像,而 C 是 uint32_t * 类型,因为它们是由 B 索引索引的。

【问题讨论】:

这不是交错,除非C 具有特定的结构。总的来说,这是一个聚会,我希望不是。 C 是什么? @harold 我知道错误的信息,谢谢。 C 是一个索引值为B 的数组。 所以这是一个普遍的集合,据我所知 NEON 没有这个 你是对的。毕竟我选择在加载时使用 vld1q_lane_u8 加载 16 个值。 【参考方案1】:

由于您没有提供很多信息,因此有点难以确定,但vqtbl1_u8 可能就是您要查找的内容。虽然 vtbl1_u8 在 armv7 上可用,但它仅适用于 AArch64。

一个简单的例子:

int main (void) 
  uint8_t bp[] =  1,  1,  2,  3,  5,  8, 13, 21 ;
  uint8_t cp[] =  0,  2,  4,  6,  1,  3,  5,  7 ;

  uint8x8_t b = vld1_u8(bp);
  uint8x8_t c = vld1_u8(cp);

  uint8x8_t a = vtbl1_u8(b, c);
  uint8_t ap[8];
  vst1_u8(ap, a);

  for (int x = 0 ; x < 8 ; x++)
    printf("%3u ", ap[x]);
  printf("\n");

  return 0;

将输出1 2 5 13 1 3 8 21

【讨论】:

帮助很大。谢谢你。但是,B 和`C` 数组的长度超过了 1000 万。可以猜到,CArray 是一个索引信息为`B`Array 的数组。我添加了一个问题以获取更多信息。

以上是关于如何在 ARM NEON SIMD 内在函数上编写“a[i]=b[c[i]]”的主要内容,如果未能解决你的问题,请参考以下文章

使用 ARM SIMD 指令优化掩码功能

二进制图像上的快速像素计数 - ARM neon 内在函数 - iOS 开发

ARM NEON 没有 xor gcc 内在函数

如何使用 ARM NEON 内在函数将 u8 掩码转换为 u32 掩码?

使用NEON优化ARM的卷积运算

(int) Image-ARM neon 内在函数上的快速图像正方形 - iOS 开发