Как я могу сделать эту функцию так же быстро, как версия vDSP? - PullRequest
0 голосов
/ 20 января 2019

Я написал нижеприведенную функцию, которая использует вызовы функций vDSP для вычисления определенного результата.Я подумал, что было бы быстрее, если бы я переписал его, используя 128-битный тип данных vFloat, чтобы избежать вызовов функций vDSP.Но мой код vFloat все еще в 2-3 раза медленнее, чем версия vDSP.

Я ориентируюсь в основном на iOS, но было бы лучше, если бы код хорошо работал и в Mac OS.

Я измеряю скорость этих функций на массивах длиной 256, что является типичнымдлина массива для моего приложения.Я хочу знать, как заставить эту функцию работать как можно быстрее, потому что у меня есть много других, подобных ей, и я надеюсь, что, как только я пойму, как оптимизировать эту функцию, я смогу использовать те же принципы для всех остальных.

Вот версия vDSP, которая в Mac OS на 50% быстрее при включенной агрессивной оптимизации или в 2-3 раза быстрее при менее агрессивных настройках компилятора:

void asymptoticLimitTest2(float limit,
                      const float* input,
                      float* output,
                      size_t numSamples){

        // input / limit => output
        vDSP_vsdiv(input, 1, &limit, output, 1, numSamples);

        // abs(output) => output
        vDSP_vabs(output, 1, output, 1, numSamples);

        // 1 + output => output
        float one = 1.0;
        vDSP_vsadd(output, 1, &one, output, 1, numSamples);

        // input / output => output
        vDSP_vdiv(output, 1, input, 1, output, 1, numSamples);
}

Вот моя версия vFloat, который я думал, будет быстрее, потому что он избегает всех вызовов функций, но для стандартного вектора длины моего приложения 256, не быстрее:

    void asymptoticLimitTest3(float limit,
                              const float* input,
                              float* output,
                              size_t numSamples){

    vFloat limitv = {limit, limit, limit, limit};
    vFloat onev = {1.0,1.0,1.0,1.0};

    size_t n = numSamples;
    // process in chunks of 8 samples
    while(n > 4){
        vFloat d = vfabsf(*(vFloat *)input / limitv) + onev;
        *(vFloat *)output = *(vFloat *)input / d;

        input += 4;
        output += 4;
        n -= 4;
    }

    // process the remaining samples individually
    while(n > 0){
        float d = fabsf(*input / limit) + 1.0;
        *output = *input / d;

        input++;
        output++;
        n--;
    }
}

Я надеюсь, что asymptoticLimitTest3 () будет работать быстрее, чемasymptoticLimitTest2 ().Мне интересно услышать все предложения, которые ускорят asymptoticLimitTest3 ()

Заранее благодарен за вашу помощь.

1 Ответ

0 голосов
/ 21 января 2019

Я провел больше тестов по времени, и оказалось, что версия vFloat, как правило, НЕ медленнее, чем версия vDSP.Когда я делал первоначальные тесты, я снова и снова вызывал одну и ту же функцию в цикле for, чтобы получить информацию о времени.Когда я переписал цикл так, чтобы он чередовал вызовы с вызовами других функций (как было бы более нормально для реального приложения), тогда версия vFloat была быстрее.По-видимому, версия vDSP получала некоторую выгоду от многократного выполнения одного и того же кода, возможно, потому что сам код оставался в кэше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...