วิธีเขียนโค้ด a[i]=b[c[i]] บนฟังก์ชัน ARM NEON SIMD Intrinsic

ฉันกำลังพยายามแปลรหัส C/C++ นี้เป็นฟังก์ชัน SIMD Intrinsic

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 (โดยใช้ฟังก์ชัน Intrinsic)

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


person Byeongju Park    schedule 04.06.2017    source แหล่งที่มา
comment
นั่นไม่ใช่การแทรกสลับ เว้นแต่ C จะมีโครงสร้างเฉพาะ โดยทั่วไปมันเป็นการรวมกลุ่ม ฉันหวังว่าจะไม่ใช่ Cคืออะไร?   -  person harold    schedule 04.06.2017
comment
@harold ฉันรู้ข้อมูลที่ผิด ขอบคุณ C เป็นอาร์เรย์ที่มีค่าดัชนีเป็น B   -  person Byeongju Park    schedule 05.06.2017
comment
ดังนั้นจึงเป็นการรวมตัวกันทั่วไป เท่าที่ฉันรู้ว่า NEON ไม่มีสิ่งนั้น   -  person harold    schedule 05.06.2017
comment
คุณพูดถูก ท้ายที่สุด ฉันเลือกที่จะโหลด 16 ค่าแต่ละค่าโดยใช้ vld1q_lane_u8 เมื่อทำการโหลด   -  person Byeongju Park    schedule 07.06.2017


คำตอบ (1)


การตรวจสอบอาจเป็นเรื่องยากเล็กน้อยเนื่องจากคุณไม่ได้ให้ข้อมูลมากนัก แต่ vqtbl1_u8 อาจเป็นสิ่งที่คุณกำลังมองหา เป็น AArch64 เท่านั้น แม้ว่า vtbl1_u8 จะพร้อมใช้งานบน armv7

ตัวอย่างด่วน:

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

person nemequ    schedule 04.06.2017
comment
มันช่วยได้มาก ขอบคุณ อย่างไรก็ตาม ความยาวของอาร์เรย์ B และ` C` นั้นมากกว่า 10 ล้าน ดังที่คุณสามารถเดาได้ C Array คืออาร์เรย์ที่มีข้อมูลดัชนีของ ` B` Array ฉันได้เพิ่มคำถามสำหรับข้อมูลเพิ่มเติม - person Byeongju Park; 05.06.2017