2009-12-06 2 views
15

iPhone 3GS 또는 Pandora에 액세스 할 수있는 사람이 방금 쓴 다음 어셈블리 루틴을 테스트 할 수 있습니까?ARMv7 + NEON 용 빠른 사인/코사인 : 테스터를 찾고 있습니다 ...

NEON 벡터 FPU에서 사인과 코사인을 정말 빠르게 계산한다고 가정합니다. 나는 그것이 잘 컴파일된다는 것을 알고 있지만 적절한 하드웨어가 없으면 그것을 테스트 할 수 없다. 몇 개의 사인과 코사인을 계산하고 그 결과를 sinf()와 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" 
    ); 
} 
+0

그냥 호기심을 - 어떤 알고리즘 죄를 빨리 계산하고 계신가요? – gahooa

+0

테스트 프로그램을 추가하면 비글 보드에서 실행할 수 있습니다. 같은 CPU. –

+0

@ gahooa : http://www.devmaster.net/forums/showthread.php?t=5784 에있는 Nicolas Capens에 의해 설명 된 방법과 cos (x) = sin (x + 90 °) – jcayzac

답변

10

그냥 비글 보드에서 테스트했습니다. 주석에서 말한 것처럼 : 동일한 CPU.

코드는 대략 clib보다 15 배 빠릅니다. 잘 했어!

각 구현 호출에 대해 82 사이클을 측정했으며 4 회의 c-lib 호출에 대해 1260 회의 측정을 수행했습니다. Soft-float ABI로 컴파일했고 OMAP3은 초기 실리콘이므로 c-lib 버전을 호출 할 때마다 NEON이 적어도 40 사이클 이상 지연됩니다.

나는

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

성능 카운터 물건은 대부분 아이폰에서 작동하지 않습니다 .. 함께 결과를 압축했습니다.

희망이 당신이 찾고 있었던 것입니다.

+0

이라는 사실을 사용합니다. Nils 대단히 감사합니다. 나는 실제로 상자 밖에서 작동하는 것에 놀랐다 :-) VFP11에 대해 구현 된 동일한 메소드는 내 iPod Touch에서 sinf() + cosf()를 호출하는 것보다 약 2 배 빠릅니다. 그래서 조회 테이블을 사용했습니다 대신. – jcayzac

+0

Ah 당신의 테스트 프로그램에서 sinf()/cosf()가 아닌 libc 함수의 배정도 변이 (sin()/cos())를 사용했다는 것을 알 수 있습니다. 그래서 libc 함수가 그렇게 잘 수행되지 않은 이유를 설명합니다 :-) – jcayzac

+0

sinf/cosf로 컴파일하고 실행하면 많은 차이가 없습니다. –

3

오 - 내가 그것을 잊어 버리기 전에 : 어쩌면 당신은 자신의 안전은 약간의 작업 ..

다음 NEON 최적화 된 수학 함수를 살펴 수행 할 수 있습니다

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

+0

예 이러한 기능을 알고 있습니다. 네온으로 놀기위한 iPhone 3GS가 있었으면 좋겠다. 물론 아이팟의 VFP11에서 작업하는 것보다 훨씬 재미있는 일이다. iPhone으로 FPU 열풍이 시작되었지만 그 전에 규칙은 다음과 같았습니다 : 부동하지 마십시오. 고정 점이 있습니다.나는 아이폰 용 수레로 코딩하는 사람들이 잘못되었다고 생각하기 시작했다. ARM은 정수에서 정말 훌륭하고 부동 레지스터를 설정하는 데 큰 오버 헤드가 있습니다. – jcayzac

+0

사실 나는 다른 관련 프로젝트가 아니라이 프로젝트를 알고 있습니다. 내가 염두에 두었던 것은 행렬/벡터 함수 만 가지고있었습니다. 링크를 삽입 한 사이트 만 선택했는지 확인하십시오. 모든 math.h 함수가있는 것처럼 보입니다! 나는 그것을 주연하고있다, 고마워! :-) – jcayzac