2017-06-04 8 views
0

J'essaie de traduire ce code C/C++ en fonction SIMD Intrinsic.Comment coder "a [i] = b [c [i]]" sur la fonction ARM NEON SIMD Intrinsic

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

Je peux traduire ci-dessous le code (C/C++)

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

au code SIMD (en utilisant la fonction Intrinsèque)

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

Je sais ce mot-clé est entrelacement pour résoudre ce problème. Mais je ne peux pas trouver de solution.

Merci.

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

Y at-il fonction Intrinsèque qui peut rendre la forme de code suivant?

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

Affichera 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

[Note]
A et B sont uint8_t types * car ils sont des images avec des valeurs comprises entre 0 et 255, et C est un type uint32_t * parce qu'ils sont indexés par indice B.

+1

Ce n'est pas entrelacer, à moins que 'C' a une structure particulière. En général, c'est un rassemblement, j'espère que ce n'est pas le cas. Qu'est-ce que 'C'? – harold

+0

@harold Je connaissais la mauvaise information, Merci. 'C' est un tableau qui a une valeur d'index de' B'. –

+1

Donc c'est un rassemblement général, autant que je sache, NEON n'a pas ça – harold

Répondre

0

Il est un peu difficile d'être sûr puisque vous n'avez pas fourni beaucoup d'informations, mais vqtbl1_u8 pourrait être ce que vous cherchez. C'est AArch64 seulement, bien que vtbl1_u8 soit disponible sur armv7.

Un exemple rapide:

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

Affichera 1 2 5 13 1 3 8 21

+0

Cela a beaucoup aidé. Je vous remercie. Cependant, la longueur des réseaux «B» et «C» est supérieure à 10 millions. Comme vous pouvez le deviner, 'C' Array est un tableau avec des informations d'index de' B' Array. J'ai ajouté une question pour plus d'informations. –