Улучшить показатели подразделения Vivado HLS

Я вычисляю инкрементное среднее моих входных данных (это массив из 6 элементов, поэтому я получу 6 средних).

Это код, который я использую каждый раз, когда доступен новый входной массив (очевидно, я обновляю количество выборок ecc...):

computing_mean:for(int i=0;i<6;i++){
       temp_mean[i]=temp_mean[i] + (input[i]-temp_mean[i])/number_of_samples;
       //Possible optimization?
       //temp_mean[i]=temp_mean[i] + divide(input[i]-temp_mean[i],number_of_samples);

}

Где все данные в коде представляют собой массивы или одно число следующего типа:

typedef ap_fixed <36,24,AP_RND_CONV,AP_SAT> decimalNumber;

Из моего сводного отчета этот цикл имеет 324 задержки и 54 задержки итерации, вызванные в основном операцией деления.

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

EDIT 1: я включаю профилировщик производительности в vivado HLS. Я добавлю автономный воспроизводимый код позже с другим редактированием. Как видите, большая часть времени уходит на SDIV введите здесь описание изображения


person Mattia Surricchio    schedule 13.10.2020    source источник
comment
Можешь векторизовать?   -  person tadman    schedule 13.10.2020
comment
Вы имеете в виду удаление цикла и выполнение операции над векторами? Я не знаю, возможно ли это в ANSII C.   -  person Mattia Surricchio    schedule 13.10.2020
comment
АНСИ С? Это какая-то устаревшая кодовая база? Векторизация просто использует SIMD-инструкции, это не функция самого C.   -  person tadman    schedule 13.10.2020
comment
Ой, извините, я новичок в этом мире (Vivado HLS). Как бы вы этого добились?   -  person Mattia Surricchio    schedule 13.10.2020
comment
Если вы спрашиваете, есть ли волшебная палочка, я могу взмахнуть этим кодом и сделать его быстрее, ответ - нет. Если вы спрашиваете, есть ли способ сделать этот код быстрее, переработав его, ответ будет длинным и сложным, но да. Сложный, но относительно простой подход состоит в том, чтобы посмотреть, сможете ли вы векторизовать это с помощью SIMD-инструкций. Более сложный, но, возможно, лучший подход — посмотреть, сможете ли вы сбросить все это на GPU и записать как функцию ядра.   -  person tadman    schedule 13.10.2020
comment
При этом я не уверен, что выполнение операций с шестью дивизиями действительно является проблемой. Это часть более крупной проблемы и может быть лишь незначительным фактором, вызывающим проблемы с производительностью.   -  person tadman    schedule 13.10.2020
comment
Вопрос второй. Я работаю внутри Vivado HLS, и мне было интересно, можно ли улучшить производительность операции разделения. Например, использовать какие-то прагмы или что-то еще (что мне пока неизвестно) для ускорения вычислений. При необходимости я могу предоставить дополнительную информацию, например, мой сводный отчет.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Например, я видел, что hls_math содержит оптимизированные арифметические функции, но, к сожалению, не доступен разделитель (по крайней мере, это то, что я видел, может быть, я ошибаюсь) для указанного типа данных.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Вы просите волшебную палочку. Не существует. Как вы думаете, почему именно эта линия является проблемой? У вас есть отчет профилировщика?   -  person tadman    schedule 13.10.2020
comment
Да, у меня есть сводный отчет со сроками, а операция по делению занимает довольно много времени. могу добавить если нужно   -  person Mattia Surricchio    schedule 13.10.2020
comment
Я действительно не думаю, что это поможет. Это проблема, которую вам придется копать самостоятельно, поскольку у вас есть доступ к остальной части кода, а у нас нет, если вы не можете сделать минимальный автономный пример, который мы можем профилировать, который воспроизводит проблему. .   -  person tadman    schedule 13.10.2020
comment
Я напишу воспроизводимый код, подожди минутку   -  person Mattia Surricchio    schedule 13.10.2020
comment
В каких единицах указаны эти числа для диаграммы задержки? Тактовые циклы или мкс?   -  person tadman    schedule 13.10.2020
comment
Это тактовые циклы   -  person Mattia Surricchio    schedule 13.10.2020
comment
Может показаться, что это много времени, но на самом деле это не так. Деление в вычислительном отношении более затратно, это правда, но в большинстве случаев оно не будет катастрофически затратным. Если у вас есть проблема с производительностью, это, вероятно, связано с одним из: промахов кеша, проблем с размещением данных, плохой структурой или принципиально неэффективным алгоритмом.   -  person tadman    schedule 13.10.2020
comment
Мне было интересно, есть ли способ оптимизировать вычисления деления, поскольку это узкое место всей моей системы (у меня нет реальной проблемы, все работает нормально, но деление — это операция, которая занимает больше всего во всей моей системе) . Все остальное имеет хорошую производительность (я мог бы оптимизировать еще больше, и я знаю, что делать), но основная проблема заключается в вычислении деления.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Помимо тригонометрических функций, таких как sin() и cos(), или таких вещей, как sqrt(), деление всегда будет наиболее болезненным. В некоторых случаях вы можете пропустить деление и вместо этого выполнить битовый сдвиг, если вы работаете с целочисленными данными, и число, на которое вы делите, является степенью двойки. , но это все.   -  person tadman    schedule 13.10.2020
comment
Вы можете добавить свой последний комментарий в качестве ответа, и я приму его.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Это int, float, double или что?   -  person tadman    schedule 13.10.2020
comment
Я написал это в вопросе, все данные в вопросе - это десятичное число, определенное в написанном мной typedef.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Вы можете перевести это на C? Если это какой-то шаткий математический тип с фиксированной точкой, это может быть проблемой. SIMD не может с этим справиться.   -  person tadman    schedule 13.10.2020
comment
Это библиотека Vivado HLS. В основном определяет число с фиксированной запятой из 36 бит с 24 битами для целой части.   -  person Mattia Surricchio    schedule 13.10.2020
comment
Думаю, вы застряли с тем, что у вас есть тогда. Я предложил возможное решение для взлома в своем ответе.   -  person tadman    schedule 13.10.2020


Ответы (1)


Помимо тригонометрических функций, таких как sin() (FSIN = ~50-170 циклов) и cos() (FCOS = ~50-120 циклов) или таких вещей, как sqrt() (FSQRT = ~22 цикла), деление всегда будет наиболее болезненным.

FDIV составляет 15 циклов. FADD и FMUL равны 5.

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

Вы можете найти приблизительную стоимость цикла ЦП для любой данной инструкции в подобных таблицах. FDIV пример дорогого.

При этом вы можете попробовать вычислить коэффициент деления заранее, а затем применить его, используя вместо этого умножение:

double inverse_n = 1 / number_of_samples;

temp_mean[i]=temp_mean[i] + (input[i]-temp_mean[i]) * inverse_n;

Я не уверен, что это сильно сэкономит, но если вам действительно нужно сократить количество циклов, попробовать стоит.

person tadman    schedule 13.10.2020