快速正弦/余弦对ARMv7 + NEON:寻找测试者... [英] Fast sine/cosine for ARMv7+NEON: looking for testers…

查看:763
本文介绍了快速正弦/余弦对ARMv7 + NEON:寻找测试者...的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能访问到iPhone 3GS或潘多拉请测试以下汇编程序我只是写?

它应该计算正弦和余弦真的快上NEON矢量FPU。我知道它编译罚款,但没有足够的硬件,我不能对它进行测试。如果你可以只计算了几个正弦和余弦,并将结果与​​SINF()和cosf(进行比较),这将真正帮助。

谢谢!

 的#include<&math.h中GT;///计算​​两个角的正弦和余弦
///在:角=两个角度,前$ P $弧度pssed,在[-PI,PI]范围内。
///出来:结果=包含载体[罪(角[0]),COS(角度[0]),罪(角[1]),COS(角度[1])
静态内嵌无效vsincos(常量浮动的角度[2],浮结果[4]){
    静态常量浮动常量[] = {
    / * * 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挥发性(
        //加载Q0与[角度1,角度1,angle2,angle2]
        vldmia%1,{} D3 \\ n \\ t的
        vdup.f​​32 D0,D3 [0] \\ n \\ t的
        vdup.f​​32 D1,D3 [1] \\ n \\ t的
        //加载Q1-Q6与常量
        vldmia%2,{Q1-Q6} \\ n \\ t的
        //的Cos(x)的= SIN(X + PI / 2),因此
        // Q0 = [角度1,角度1 + PI / 2,angle2,angle2 + PI / 2]
        vadd.f32 Q0,Q0,Q1 \\ n \\ t的
        //如果角度1 + PI / 2 - ; PI,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(结果),R(角度),R(常量)
        :记忆,抄送,Q0,Q1,Q2,Q3,第四季度,Q5,Q6
    );
}


解决方案

只是测试它在我的BeagleBoard。由于在评论中说:同CPU

您code比CLIB ..那么快完成约15倍!

我测量82个周期的实施和1260四个C-lib中调用每个调用。请注意,我编译软浮ABI和我的OMAP3是早期硅,所以每次调用的C库版本至少有40个周期的NEON摊位。

我一起压缩的结果。

<一个href=\"http://torus.untergrund.net/$c$c/sincos.zip\">http://torus.untergrund.net/$c$c/sincos.zip

性能计数器的东西很可能不会在iPhone上工作。

希望这是你一直在寻找的东西。

Could somebody with access to an iPhone 3GS or a Pandora please test the following assembly routine I just wrote?

It is supposed to compute sines and cosines really really fast on the NEON vector FPU. I know it compiles fine, but without adequate hardware I can't test it. If you could just compute a few sines and cosines and compare the results with those of sinf() and cosf() it would really help.

Thanks!

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

解决方案

Just tested it on my beagleboard.. As said in the comments: Same CPU.

Your code is roughly 15 times faster than the clib.. Well done!

I've measured 82 cycles for each call of your implementation and 1260 for the four c-lib calls. Note that I've compiled with soft-float ABI and my OMAP3 is early silicon, so each call to the the c-lib version has a NEON stall of at least 40 cycles.

I've zipped together the results..

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

The performance-counter stuff will most likely not work on the iphone.

Hope that's what you've been looking for.

这篇关于快速正弦/余弦对ARMv7 + NEON:寻找测试者...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆