2009-12-06 14 views
15

Potrebbe qualcuno con accesso ad un iPhone 3GS o un vaso di Pandora si prega di verificare il seguente routine assembly che ho appena scritto?veloce seno/coseno per ARMv7 + NEON: alla ricerca di tester ...

Si suppone per calcolare seni e coseni veramente veramente veloce sulla FPU NEON vettoriale. So che si compila bene, ma senza un hardware adeguato non posso testarlo. Se potessi calcolare solo pochi seni e coseni e confrontare i risultati con quelli di sinf() e cosf(), sarebbe davvero d'aiuto.

Grazie!

#include <math.h> 

/// Computes the sine and cosine of two angles 
/// in: angles = Two angles, expressed in radians, in the [-PI,PI] range. 
/// out: results = vector containing [sin(angles[0]),cos(angles[0]),sin(angles[1]),cos(angles[1])] 
static inline void vsincos(const float angles[2], float results[4]) { 
    static const float constants[] = { 
    /* q1 */ 0,    M_PI_2,   0,    M_PI_2, 
    /* q2 */ M_PI,    M_PI,    M_PI,    M_PI, 
    /* q3 */ 4.f/M_PI,   4.f/M_PI,   4.f/M_PI,   4.f/M_PI, 
    /* q4 */ -4.f/(M_PI*M_PI), -4.f/(M_PI*M_PI), -4.f/(M_PI*M_PI), -4.f/(M_PI*M_PI), 
    /* q5 */ 2.f,    2.f,    2.f,    2.f, 
    /* q6 */ .225f,   .225f,   .225f,   .225f 
    }; 
    asm volatile(
     // Load q0 with [angle1,angle1,angle2,angle2] 
     "vldmia %1, { d3 }\n\t" 
     "vdup.f32 d0, d3[0]\n\t" 
     "vdup.f32 d1, d3[1]\n\t" 
     // Load q1-q6 with constants 
     "vldmia %2, { q1-q6 }\n\t" 
     // Cos(x) = Sin(x+PI/2), so 
     // q0 = [angle1, angle1+PI/2, angle2, angle2+PI/2] 
     "vadd.f32 q0,q0,q1\n\t" 
     // if angle1+PI/2>PI, substract 2*PI 
     // q0-=(q0>PI)?2*PI:0 
     "vcge.f32 q1,q0,q2\n\t" 
     "vand.f32 q1,q1,q2\n\t" 
     "vmls.f32 q0,q1,q5\n\t" 
     // q0=(4/PI)*q0 - q0*abs(q0)*4/(PI*PI) 
     "vabs.f32 q1,q0\n\t" 
     "vmul.f32 q1,q0,q1\n\t" 
     "vmul.f32 q0,q0,q3\n\t" 
     "vmul.f32 q1,q1,q4\n\t" 
     "vadd.f32 q0,q0,q1\n\t" 
     // q0+=.225*(q0*abs(q0) - q0) 
     "vabs.f32 q1,q0\n\t" 
     "vmul.f32 q1,q0,q1\n\t" 
     "vsub.f32 q1,q0\n\t" 
     "vmla.f32 q0,q1,q6\n\t" 
     "vstmia %0, { q0 }\n\t" 
     :: "r"(results), "r"(angles), "r"(constants) 
     : "memory","cc","q0","q1","q2","q3","q4","q5","q6" 
    ); 
} 
+0

Solo curioso - l'algoritmo stai usando per calcolare il peccato velocemente, cos? – gahooa

+0

se aggiungi un programma di test posso eseguirlo sul mio beagleboard ... Stessa CPU. –

+0

@gahooa: Uso il metodo descritto da Nicolas Capens su http://www.devmaster.net/forums/showthread.php?t=5784 e il fatto che cos (x) = sin (x + 90 °) – jcayzac

risposta

10

Appena testato sul mio beagleboard .. Come detto nei commenti: stessa CPU.

Il codice è di circa 15 volte più veloce rispetto al CLIB .. Complimenti!

ho misurato 82 cicli per ogni chiamata della vostra implementazione e il 1260 per le chiamate quattro c-lib. Nota che ho compilato con ABI soft-float e il mio OMAP3 è presto silicio, quindi ogni chiamata alla versione c-lib ha uno stallo NEON di almeno 40 cicli.

ho compressi insieme i risultati ..

http://torus.untergrund.net/code/sincos.zip

La roba prestazioni da banco molto probabilmente non funziona su iPhone.

Spero che sia quello che stavate cercando.

+0

Grazie mille Nils. Sono un po 'sorpreso che abbia funzionato fuori dagli schemi, in realtà :-) Lo stesso metodo implementato per VFP11 è circa il doppio della velocità di chiamare sinf() + cosf() sul mio iPod Touch, quindi ho usato una tabella di ricerca anziché. – jcayzac

+0

Ah, vedo dal tuo programma di test che hai usato la variante a doppia precisione della funzione libc (sin()/cos(), non sinf()/cosf()). Questo spiega perché le funzioni di libc sono state eseguite così male penso :-) – jcayzac

+0

Appena compilato ed eseguito con sinf/cosf, e non fa molta differenza. –

3

Oh - da non dimenticare: Forse si può sicuro voi stessi un po 'di lavoro ..

Date un'occhiata a queste funzioni matematiche NEON ottimizzato:

http://code.google.com/p/math-neon/

+0

Sì, conosco queste funzioni. Mi piacerebbe avere un iPhone 3GS per giocare con NEON, che è sicuramente molto più divertente di lavorare sul mio iPod VFP11. Con l'iPhone è iniziata una mania della FPU, ma prima la regola era: NON fare galleggianti, FARE punto fisso.Sto iniziando a pensare che i ragazzi che codificano con i float per l'iPhone abbiano torto. ARM è davvero buono con gli interi e l'impostazione dei registri float ha un grande sovraccarico. – jcayzac

+0

In effetti conosco un altro progetto correlato, non questo. Quello che avevo in mente aveva solo funzioni matrice/vettoriale. Appena controllato quello a cui metti un link. Sembra che abbia tutte le funzioni di math.h! Lo sto facendo, grazie! :-) – jcayzac

Problemi correlati