سؤال

هل يمكن لشخصي الوصول إلى iPhone 3GS أو باندورا يرجى اختبار روتين التجمع التالي كتبته للتو؟

من المفترض أن يحسب sines و sposines حقا بسرعة حقا على نيون ناقلات FPU. أعلم أنه يجمع بشكل جيد، ولكن بدون أجهزة كافية لا أستطيع اختبارها. إذا كان بإمكانك حساب عدد قليل من سينات وتضاعف وقارن بين النتائج مع هؤلاء من سينف () و COSF () سيساعد حقا.

شكرًا!

#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"
    );  
}
هل كانت مفيدة؟

المحلول

فقط اختبارها على بلدي beagleboard .. كما قال في التعليقات: نفس وحدة المعالجة المركزية.

الكود الخاص بك هو تقريبا 15 مرة أسرع من clib .. حسنا فعلت!

لقد قمت بقياس 82 دورة لكل مكالمة لتنفيذك و 1260 للمكالمات الأربعة C-LIB. لاحظ أنني قمت بتجميعها مع Soft-Float ABI و My Omap3 هو السيليكون في وقت مبكر، لذلك كل مكالمة إلى إصدار C-Lib يحتوي على كشك نيون من 40 دورة على الأقل.

لقد مضغوط معا النتائج ..

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

من المرجح أن لا تعمل الأشياء المضادة للأداء على iPhone.

آمل أن يكون هذا ما كنت تبحث عنه.

نصائح أخرى

أوه - قبل أن أنسى ذلك: ربما يمكنك آمنة نفسك قليلا ..

نلقي نظرة على هذه وظائف الرياضيات المحسنة هذه:

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top