Question

Quelqu'un pourrait-il accès à un iPhone 3GS ou Pandore s'il vous plaît tester la routine de montage suivant, je viens d'écrire?

Il est censé calculer et Sines vraiment très rapide cosinus sur le vecteur NEON FPU. Je sais qu'il compile très bien, mais sans matériel adéquat, je ne peux pas tester. Si vous pouviez calculer quelques sinus et cosinus et de comparer les résultats avec ceux des sinf () et cosf (), il serait vraiment utile.

Merci!

#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"
    );  
}
Était-ce utile?

La solution

Il suffit de tester sur mon beagleboard .. Comme dit dans les commentaires:. CPU même

Votre code est environ 15 fois plus rapide que le clib .. Eh bien fait!

J'ai mesuré 82 cycles pour chaque appel de votre mise en œuvre et 1260 pour les quatre appels c-lib. Notez que j'ai compilé avec ABI soft-float et mon OMAP3 est au début du silicium, de sorte que chaque appel à la version c-lib a un étal de NEON d'au moins 40 cycles.

Je suis zippé ensemble les résultats ..

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

Les choses performance contre sera très probablement pas fonctionner sur l'iPhone.

L'espoir que ce que vous avez cherché.

Autres conseils

Oh - avant que je l'oublie: Peut-être que vous pouvez vous en toute sécurité un peu de travail ..

Jetez un oeil à ces fonctions mathématiques optimisées NEON:

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top