Как я могу повторить ускорение (библиотека Apple DSP) функции в Windows? - PullRequest
2 голосов
/ 17 февраля 2012

Я собираюсь сделать это как можно более кратким:

У меня есть проект, который мне нужно портировать на Windows из-за некоторых очень специфических аппаратных ограничений. Есть небольшой служебный класс, который выполняет вычисления векторного расстояния с использованием Accelerate, библиотеки Apple DSP. Мне нужно переписать это так, чтобы он функционировал без указанной библиотеки, но не смог найти подходящую замену. Какой мой лучший образ действий?

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

Ответы [ 2 ]

4 голосов
/ 17 февраля 2012

Векторные функции обычно реализуются с помощью инструкций на языке ассемблера. Эта реализация очень медленная. Возможно, вам нужна библиотека, которая использует инструкции SSE.

В вашем коде все аргументы stride_x, stride_y, stride_res равны 1, поэтому я рекомендую вам удалить их из аргументов функций. Код должен быть быстрее.

//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--;
    }    
}
2 голосов
/ 17 февраля 2012

Посмотрите библиотеки Intel IPP .

...