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

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

问题描述

可以使用 iPhone 3GS 或 Pandora 的人请测试我刚刚编写的以下组装例程吗?

它应该在 NEON 矢量 FPU 上非常快速地计算正弦和余弦.我知道它编译得很好,但没有足够的硬件我无法测试它.如果您可以只计算一些正弦和余弦,并将结果与​​ sinf() 和 cosf() 的结果进行比较,那真的会很有帮助.

谢谢!

#include ///计算两个角度的正弦和余弦///in:angles = 两个角度,以弧度表示,在 [-PI,PI] 范围内.///out: results = vector contains [sin(angles[0]),cos(angles[0]),sin(angles[1]),cos(angles[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};汇编易变(//用 [angle1,angle1,angle2,angle2] 加载 q0"vldmia %1, { d3 }\n\t""vdup.f32 d0, d3[0]\n\t""vdup.f32 d1, d3[1]\n\t"//用常量加载 q1-q6"vldmia %2, { q1-q6 }\n\t"//Cos(x) = Sin(x+PI/2),所以//q0 = [角度1,角度1+PI/2,角度2,角度2+PI/2]"vadd.f32 q0,q0,q1\n\t"//如果angle1+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"(常数):内存"、cc"、q0"、q1"、q2"、q3"、q4"、q5"、q6");}

解决方案

刚刚在我的 beagleboard 上进行了测试.如评论中所说:相同的 CPU.

您的代码大约比 clib 快 15 倍.做得好!

对于您的实现的每次调用,我测量了 82 个周期,四个 c-lib 调用测量了 1260 个周期.请注意,我使用 soft-float ABI 进行编译,并且我的 OMAP3 是早期芯片,因此每次调用 c-lib 版本都会有至少 40 个周期的 NEON 停顿.

我已将结果压缩在一起..

http://torus.untergrund.net/code/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天全站免登陆