Точечный продукт NEON SIMD не быстрее на ARM Cortex A53

arm simd neon dot-product

789 просмотра

1 ответ

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

Вот мой код с SIMD:

        float output = 0.0;

    for (int i=0; i<NUMBER_OF_INPUTS; i+=4)
    {
        in1_126 = vld1q_f32(&source[i]);
        in2_126 = vld1q_f32(&weights[i]);
        out_126 = vmulq_f32(in1_126, in2_126);
        output +=  vaddvq_f32(out_126);
    }

    return output;  

а тут без:

    float output = 0.0;
    float tmp;



    for(unsigned int i = 0; i < NUMBER_OF_INPUTS; i++)
    {
        tmp = source[i] * weights[i];
        output += tmp;  
    }

    return output;  

Я установил эти флаги компилятора:

-mcpu=cortex-a53 -march=armv8-a+simd+crypto

но это ничего не меняет.

Почему почти нет разницы во времени? Или использование NEON - неправильный путь, чтобы ускорить мой продукт? У вас есть другие идеи, чтобы сделать это быстрее?

Спасибо за любой ответ!

Автор: J.Ney Источник Размещён: 13.10.2019 05:33

Ответы (1)


3 плюса

Решение

Вы не должны переходить от векторного регистра к скалярному регистру внутри циклов.

Это приведет к очистке конвейера и будет стоить вам примерно 14 циклов каждый раз, когда это происходит. (на ARMv7-A)

Сколько это циклов, зависит от конкретной архитектуры.

То, что вы можете попробовать:

out126 = vmovq_n_f32(0.0f);
for (int i=0; i<NUMBER_OF_INPUTS; i+=4)
{
  in1_126 = vld1q_f32(&source[i]);
  in2_126 = vld1q_f32(&weights[i]);
  out_126 = vmlaq_f32(out_126, in1_126, in2_126);
}

output =  vaddvq_f32(out_126);
Автор: Jake 'Alquimista' LEE Размещён: 22.12.2017 10:11
Вопросы из категории :
32x32