Voici un code C++:
#define ARR_SIZE_TEST ( 8 * 1024 * 1024 )
void cpp_tst_add( unsigned* x, unsigned* y )
{
for ( register int i = 0; i < ARR_SIZE_TEST; ++i )
{
x[ i ] = x[ i ] + y[ i ];
}
}
Voici un néon version:
void neon_assm_tst_add( unsigned* x, unsigned* y )
{
register unsigned i = ARR_SIZE_TEST >> 2;
__asm__ __volatile__
(
".loop1: \n\t"
"vld1.32 {q0}, [%[x]] \n\t"
"vld1.32 {q1}, [%[y]]! \n\t"
"vadd.i32 q0 ,q0, q1 \n\t"
"vst1.32 {q0}, [%[x]]! \n\t"
"subs %[i], %[i], $1 \n\t"
"bne .loop1 \n\t"
: [x]"+r"(x), [y]"+r"(y), [i]"+r"(i)
:
: "memory"
);
}
Fonction de Test:
void bench_simple_types_test( )
{
unsigned* a = new unsigned [ ARR_SIZE_TEST ];
unsigned* b = new unsigned [ ARR_SIZE_TEST ];
neon_tst_add( a, b );
neon_assm_tst_add( a, b );
}
J'ai testé les deux variantes et voici le rapport:
add, unsigned, C++ : 176 ms
add, unsigned, neon asm : 185 ms // SLOW!!!
J'ai aussi testé d'autres types:
add, float, C++ : 571 ms
add, float, neon asm : 184 ms // FASTER X3!
LA QUESTION: Pourquoi le néon est plus lent avec l'entier de 32 bits types?
J'ai utilisé la dernière version de GCC pour Android NDK. NEON options d'optimisation qui ont été activées. Voici une démonté C++ version:
MOVS R3, #0
PUSH {R4}
loc_8
LDR R4, [R0,R3]
LDR R2, [R1,R3]
ADDS R2, R4, R2
STR R2, [R0,R3]
ADDS R3, #4
CMP.W R3, #0x2000000
BNE loc_8
POP {R4}
BX LR
Ici est démonté version du néon:
MOV.W R3, #0x200000
.loop1
VLD1.32 {D0-D1}, [R0]
VLD1.32 {D2-D3}, [R1]!
VADD.I32 Q0, Q0, Q1
VST1.32 {D0-D1}, [R0]!
SUBS R3, #1
BNE .loop1
BX LR
Voici tous les bancs de tests:
add, char, C++ : 83 ms
add, char, neon asm : 46 ms FASTER x2
add, short, C++ : 114 ms
add, short, neon asm : 92 ms FASTER x1.25
add, unsigned, C++ : 176 ms
add, unsigned, neon asm : 184 ms SLOWER!!!
add, float, C++ : 571 ms
add, float, neon asm : 184 ms FASTER x3
add, double, C++ : 533 ms
add, double, neon asm : 420 ms FASTER x1.25
LA QUESTION: Pourquoi le néon est plus lent avec l'entier de 32 bits types?