2012-02-16 6 views
1

필자는 이것을 다음과 같이 간결하게 만들 것입니다.어떻게 윈도우에서 가속 (사과 DSP 라이브러리) 기능을 복제 할 수 있습니까?

매우 구체적인 하드웨어 제약으로 인해 Windows로 포팅해야하는 프로젝트가 있습니다. Apple DSP 라이브러리 인 Accelerate를 사용하여 벡터 거리 계산을 수행하는 작은 유틸리티 클래스가 있습니다. 나는 라이브러리를 사용하지 않고 기능을 수행 할 수 있도록 다시 작성해야하지만 적합한 대체품을 찾을 수 없습니다. 최선의 행동 방침은 무엇입니까?

#include <Accelerate/Accelerate.h> 

inline float distBetween(float *x, float *y, unsigned int count) { 
    float *tmp = (float*)malloc(count * sizeof(float)); 
    // float tmp[count]; 
    //t = y - x 
    vDSP_vsub(x, 1, y, 1, tmp, 1, count); 
    //t.squared 
    vDSP_vsq(tmp, 1, tmp, 1, count); 
    //t.sum 
    float sum; 
    vDSP_sve(tmp, 1, &sum, count); 
    delete tmp; 
    return sqrt(sum); 
} 

inline float cosineDistance(float *x, float *y, unsigned int count) { 
    float dotProd, magX, magY; 
    float *tmp = (float*)malloc(count * sizeof(float)); 

    vDSP_dotpr(x, 1, y, 1, &dotProd, count); 

    vDSP_vsq(x, 1, tmp, 1, count); 
    vDSP_sve(tmp, 1, &magX, count); 
    magX = sqrt(magX); 

    vDSP_vsq(y, 1, tmp, 1, count); 
    vDSP_sve(tmp, 1, &magY, count); 
    magY = sqrt(magY); 

    delete tmp; 

    return 1.0 - (dotProd/(magX * magY)); 
} 

답변

3

벡터 기능은 일반적으로 특정 어셈블리 언어 지침을 통해 구현됩니다. 이 구현은 매우 느립니다. 아마도 SSE 지침을 사용하는 라이브러리가 필요할 것입니다.

코드에서 stride_x, stride_y, stride_res의 모든 인수가 1이므로 함수 인수에서 제거하는 것이 좋습니다. Сode가 빨라야합니다.

//t = y - x  
float 
vDSP_vsub(float *x, int stride_x, float *y, int stride_y, float *res, int stride_res, int count) 
{ 
    while(count > 0) 
    { 
     // may be *x - *y ? 
     *res = *y - *x; 
     res += stride_res; 
     x += stride_x; 
     y += stride_y; 
     count--; 
    }  
} 

//t.squared 
float 
vDSP_vsq(float *x, int stride_x, float *res, int stride_res, int count) 
{ 
    while(count > 0) 
    { 
     *res += (*x) * (*x); 
     x += stride_x; 
     res += stride_res; 
     count--; 
    }  
} 

//t.sum 
float 
vDSP_sve(float *x, int stride_x, float *res, int count) 
{ 
    *res = 0.0; 
    while(count > 0) 
    { 
     *res += *x; 
     x += stride_x; 
     count--; 
    }  
} 

float 
vDSP_dotpr(float *x, int stride_x, float *y, int stride_y, float *res, int count) 
{ 
    *res = 0.0; 
    while(count > 0) 
    { 
     *res += (*x) * (*y); 
     x += stride_x; 
     y += stride_y; 
     count--; 
    }  
}