Cara membuat kode a[i]=b[c[i]] pada fungsi Intrinsik ARM NEON SIMD

Saya mencoba menerjemahkan kode C/C++ ini ke fungsi SIMD Intrinsik.

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

Saya dapat menerjemahkan kode di bawah ini (C/C++)

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

ke kode SIMD (menggunakan fungsi Intrinsik)

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

Saya tahu kata kunci itu disisipkan untuk menyelesaikan masalah ini. Tapi saya tidak dapat menemukan solusi.

Terima kasih.

Edit
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.

Apakah ada fungsi intrinsik yang dapat membuat bentuk kode berikut?

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);
}

Akan menghasilkan 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

[Catatan]
A dan B adalah tipe uint8_t * karena merupakan gambar dengan nilai antara 0 dan 255, dan C adalah tipe uint32_t * karena diindeks oleh indeks B.


person Byeongju Park    schedule 04.06.2017    source sumber
comment
Itu bukan interleaving, kecuali C memiliki struktur tertentu. Secara umum ini adalah pertemuan, saya harap tidak. Apa itu C?   -  person harold    schedule 04.06.2017
comment
@harold Saya tahu informasi yang salah, Terima kasih. C adalah array yang memiliki nilai indeks B.   -  person Byeongju Park    schedule 05.06.2017
comment
Jadi ini pertemuan umum, setahu saya NEON tidak punya itu   -  person harold    schedule 05.06.2017
comment
Kamu benar. Lagi pula, saya memilih untuk memuat 16 nilai masing-masing menggunakan vld1q_lane_u8 saat memuat.   -  person Byeongju Park    schedule 07.06.2017


Jawaban (1)


Agak sulit untuk memastikannya karena Anda tidak memberikan banyak informasi, tetapi vqtbl1_u8 mungkin yang Anda cari. Ini hanya AArch64, meskipun vtbl1_u8 tersedia di armv7.

Contoh singkat:

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;
}

Akan menghasilkan 1 2 5 13 1 3 8 21

person nemequ    schedule 04.06.2017
comment
Ini telah banyak membantu. Terima kasih. Namun, panjang array B dan` C` lebih dari 10 juta. Seperti yang bisa Anda tebak, C Array adalah array dengan informasi indeks` B` Array. Saya telah menambahkan pertanyaan untuk informasi lebih lanjut. - person Byeongju Park; 05.06.2017