реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> аппроксимация деления, почему не используется
alexkarnaukhov
сообщение May 13 2015, 22:57
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873



У меня стоит задача нормировки потока чисел (поток пикселей изображения) на некоторое переменное значение (например разницу максимальной и минимальной яркости изображения). Соответственно без деления не обойтись. Те алгоритмы, которые используются чаще всего, делятся на два типа: либо тупо LUT с забитой таблицей 1/х, либо итеративные алгоритмы, имитирующие деление в столбик, с различной степенью оптимизации. Еще можно складывать делитель, пока результат не превзойдет делимое и посчитать количество таких операций, но это совсем плохой алгоритм.

Почему никто не использует тупо полиномиальную аппроксимацию 1/х? Вот здесь всего навсего полином 3-й степени, 100 слайсов на 3-ем Спартане и при этом точность 11 бит. Мне так кажется, что я здесь что-то не понимаю, это же так просто, почему так не делают?
Еще и конкретно для моей задачи - даже при точности 11 бит, я мог бы получить приемлемый результат, забив на линейность нормировки.

Спасибо.
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение May 14 2015, 04:16
Сообщение #2


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



..я пользуюсь сдвигом вправо.


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 14 2015, 05:11
Сообщение #3


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(alexkarnaukhov @ May 14 2015, 01:57) *
У меня стоит задача нормировки потока чисел (поток пикселей изображения) на некоторое переменное значение (например разницу максимальной и минимальной яркости изображения). Соответственно без деления не обойтись. Те алгоритмы, которые используются чаще всего, делятся на два типа: либо тупо LUT с забитой таблицей 1/х, либо итеративные алгоритмы, имитирующие деление в столбик, с различной степенью оптимизации. Еще можно складывать делитель, пока результат не превзойдет делимое и посчитать количество таких операций, но это совсем плохой алгоритм.

Почему никто не использует тупо полиномиальную аппроксимацию 1/х? Вот здесь всего навсего полином 3-й степени, 100 слайсов на 3-ем Спартане и при этом точность 11 бит. Мне так кажется, что я здесь что-то не понимаю, это же так просто, почему так не делают?
Еще и конкретно для моей задачи - даже при точности 11 бит, я мог бы получить приемлемый результат, забив на линейность нормировки.

Спасибо.

Вот например целочисленное деление не подходит?
Какая частота съема пикселей? Разрядность пикселей? Какая плис?
PS в крайнем случае можно сделать pipeline деление...


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
des00
сообщение May 14 2015, 05:32
Сообщение #4


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(alexkarnaukhov @ May 14 2015, 05:57) *
даже при точности 11 бит, я мог бы получить приемлемый результат, забив на линейность нормировки.

собственно вот и ответ на ваш вопрос.

ЗЫ. деление в столбик будет делить точно, при конвейере будет 1 слово за такт. и для ваших 11 бит составит немногим больше 100 слайсов.


--------------------
Go to the top of the page
 
+Quote Post
alexkarnaukhov
сообщение May 14 2015, 10:32
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873



Цитата(Maverick @ May 14 2015, 09:11) *
Вот например целочисленное деление не подходит?
Какая частота съема пикселей? Разрядность пикселей? Какая плис?
PS в крайнем случае можно сделать pipeline деление...

Частота - 50МГц, 14бит, плис - 7я серия xilinx. На данный момент для деления использую корку DividerGenerator в режиме Radix-2. Хавает более 2000 FF... pipeline нужен обязательно, а вот latency роли не играет, хоть 1000 тактов пойдет. Ваш алгоритм, насколько я понимаю, несколько тактов на деление требует? Я боюсь, что если его конвейеризировать, то слайсов будет прилично занимать...
И все-таки в аппроксимации меня привлекает то, что результат-то можно получать гораздо большей разрядности, чем наихудшую точность (ну как в АЦП - есть разрядность, а есть нелинейность и в плохом АЦП может быть 16 эффективных разрядов, но линейными могут быть только 14). Т.е. можно получить монотонную 16-битную функцию на выходе, у которой только первые 11 бит будут всегда точно соответствовать 1/х, что вполне может сгодиться. Делением в столбик такого не получишь...
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 14 2015, 10:44
Сообщение #6


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(alexkarnaukhov @ May 14 2015, 13:32) *
Частота - 50МГц, 14бит, плис - 7я серия xilinx. На данный момент для деления использую корку DividerGenerator в режиме Radix-2. Хавает более 2000 FF... pipeline нужен обязательно, а вот latency роли не играет, хоть 1000 тактов пойдет. Ваш алгоритм, насколько я понимаю, несколько тактов на деление требует? Я боюсь, что если его конвейеризировать, то слайсов будет прилично занимать...
И все-таки в аппроксимации меня привлекает то, что результат-то можно получать гораздо большей разрядности, чем наихудшую точность (ну как в АЦП - есть разрядность, а есть нелинейность и в плохом АЦП может быть 16 эффективных разрядов, но линейными могут быть только 14). Т.е. можно получить монотонную 16-битную функцию на выходе, у которой только первые 11 бит будут всегда точно соответствовать 1/х, что вполне может сгодиться. Делением в столбик такого не получишь...

думаю будет меньше чем 2000 FF

upd

для 16 битных данных
Цитата
Flow Status Successful - Thu May 14 14:49:58 2015
Quartus II 64-Bit Version 13.0.1 Build 232 06/12/2013 SP 1 SJ Full Version
Family Stratix IV
Logic utilization < 1 %
Combinational ALUTs 46 / 58,080 ( < 1 % )
Memory ALUTs 0 / 29,040 ( 0 % )
Dedicated logic registers 85 / 58,080 ( < 1 % )
Total registers 85
Total pins 67 / 584 ( 11 % )
Device EP4SGX70HF35C2
Timing Models Final


таймквет показывает частоту выше 300 МГц

Как вариант можно блок деления запустить на частоте эдак 300МГц.

300МГц/50МГц = 6

Ставим 3 (с запасом) модуля и переиспользуем ресурсы.
Таким образом, Вы получаете на 3 модулях pipeline на 3*6=18 тактов
Минимизация ресурсов налицо за счет временного мультиплексирования и переиспользования ресурса (модуля деления)...
------------------------------------------------------------------------------------------------------------------------------------------------------------
Даже если просто (для работы на одной тактовой частоте 50МГц)
85 регистров *16 = 1 360
то и здесь получается экономия

только что увидел у Вас не 16 бит а 14 бит данные, тогда еще больше экономии...


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
_pv
сообщение May 14 2015, 10:59
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



если в a/b делитель не так часто меняется, посчитайте как угодно медленно один раз с=(2^n)/b и потом множьте на него за такт и сдвигайте.
Go to the top of the page
 
+Quote Post
alexkarnaukhov
сообщение May 14 2015, 11:13
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873



Цитата(_pv @ May 14 2015, 14:59) *
если в a/b делитель не так часто меняется, посчитайте как угодно медленно один раз с=(2^n)/b и потом множьте на него за такт и сдвигайте.

С нормировкой кадра такое прокатит, а вот когда множитель для каждого пикселя меняется (а такое тоже надо) - уже нет
Go to the top of the page
 
+Quote Post
XVR
сообщение May 14 2015, 11:17
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(alexkarnaukhov @ May 14 2015, 01:57) *
Почему никто не использует тупо полиномиальную аппроксимацию 1/х? Вот здесь всего навсего полином 3-й степени. Мне так кажется, что я здесь что-то не понимаю, это же так просто, почему так не делают?
Наверное потому, что x должно быть в пределах от 1 до 2х (в той же статье написано). Может не хватить диапазона.

Go to the top of the page
 
+Quote Post
alexkarnaukhov
сообщение May 14 2015, 11:29
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873



Цитата(XVR @ May 14 2015, 15:17) *
Наверное потому, что x должно быть в пределах от 1 до 2х (в той же статье написано). Может не хватить диапазона.


Да, есть такое. Адекватно аппроксимировать 1/х и возле нуля и на хвосте невозможно... Хотя, как в той же статье, можно попытаться разбить область определения на несколько сегментов и в каждом сегменте использовать свои коэффициенты для полинома... Считать полиномы посложнее будет - надо концы сегментов согласовывать, т.е. решать задачу с закрепленными концами, но все-таки мне кажется такой поход интересным...
Go to the top of the page
 
+Quote Post
vladec
сообщение May 15 2015, 05:45
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 167
Регистрация: 3-10-05
Из: Москва
Пользователь №: 9 158



Для вычисления 1/x есть еще итерационные алгоритмы, для них характерна очень быстрая сходимость, в том числе и на больших разрядностях
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 15 2015, 05:53
Сообщение #12


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(vladec @ May 15 2015, 08:45) *
Для вычисления 1/x есть еще итерационные алгоритмы, для них характерна очень быстрая сходимость, в том числе и на больших разрядностях

например? (хорошие по Вашему мнению - 32/64 бит)


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
blackfin
сообщение May 15 2015, 09:46
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 106
Регистрация: 18-04-05
Пользователь №: 4 261



Цитата(Maverick @ May 15 2015, 08:53) *
например? (хорошие по Вашему мнению - 32/64 бит)

Ну можно, наверное, методом Ньютона попробовать.. biggrin.gif

Главное - выбрать правильное начальное приближение.. wink.gif

Например, мы хотим найти частное от деления: A/B = D, где A = 555555, B = 11 и, соответственно, D = 50505.

Тогда:

A/B = [(A*232/B)>>32] = D.

Введем обозначение:

x = 232/B.

Это равносильно:

232/x = B.

Или:

f(x) == 232/x - B = 0.

Находим производную:

f'(x) = -232/x2.

Теперь подставляем всё это в формулу Ньютона и находим:

xn+1 = xn - f(xn)/f'(xn), или

xn+1 = xn + [232/xn - B]/[232/xn2], или

xn+1 = 2*xn - B*xn2/232, или

xn+1 = 2*xn - [(B*xn*xn)>>32].

Начальное приближение для x0 выбираем равным:

x0 = 232-m, где m - максимальная степень двойки в двоичном представлении числа B..

То есть, для B = 11 это дает:

B = 11d = 1011b = 1*23 + 0*22 + 1*21 + 1*20.

Откуда находим, что m = 3, и:

x0 = 229.

Тогда:

x1 = 230 - 11*226 = 335544320;

x2 = 2*335544320 - (11*335544320*335544320)>>32 = 382730240;

x3 = 2*382730240 - (11*382730240*382730240)>>32 = 390298880;

x4 = 2*390298880 - (11*390298880*390298880)>>32 = 390451513;

x5 = 2*390451513 - (11*390451513*390451513)>>32 = 390451572;

x6 = 2*390451572 - (11*390451572*390451572)>>32 = 390451572;

После чего находим:

A/B = [(A*x)>>32] = [(555555*390451572)>>32] = 50505 = D.

Но в целом, все эти "быстро сходящиеся итерации" не слишком то оптимальны для FPGA, КМК..

Как-то так..

biggrin.gif
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 15 2015, 10:28
Сообщение #14


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(blackfin @ May 15 2015, 12:46) *
Ну можно, наверное, методом Ньютона попробовать.. biggrin.gif

Главное - выбрать правильное начальное приближение.. wink.gif

Например, мы хотим найти частное от деления: A/B = D, где A = 555555, B = 11 и, соответственно, D = 50505.

Тогда:

A/B = [(A*232/B)>>32] = D.

Введем обозначение:

x = 232/B.

Это равносильно:

232/x = B.

Или:

f(x) == 232/x - B = 0.

Находим производную:

f'(x) = -232/x2.

Теперь подставляем всё это в формулу Ньютона и находим:

xn+1 = xn - f(xn)/f'(xn), или

xn+1 = xn + [232/xn - B]/[232/xn2], или

xn+1 = 2*xn - B*xn2/232, или

xn+1 = 2*xn - [(B*xn*xn)>>32].

Начальное приближение для x0 выбираем равным:

x0 = 232-m, где m - максимальная степень двойки в двоичном представлении числа B..

То есть, для B = 11 это дает:

B = 11d = 1011b = 1*23 + 0*22 + 1*21 + 1*20.

Откуда находим, что m = 3, и:

x0 = 229.

Тогда:

x1 = 230 - 11*226 = 335544320;

x2 = 2*335544320 - (11*335544320*335544320)>>32 = 382730240;

x3 = 2*382730240 - (11*382730240*382730240)>>32 = 390298880;

x4 = 2*390298880 - (11*390298880*390298880)>>32 = 390451513;

x5 = 2*390451513 - (11*390451513*390451513)>>32 = 390451572;

x6 = 2*390451572 - (11*390451572*390451572)>>32 = 390451572;

После чего находим:

A/B = [(A*x)>>32] = [(555555*390451572)>>32] = 50505 = D.

Но в целом, все эти "быстро сходящиеся итерации" не слишком то оптимальны для FPGA, КМК..

Как-то так..

biggrin.gif

спасибо...

PS метод Ньютон работает для нахождения практически любых функций и как Вы правильно заметили для FPGA в чистом виде плохо подходят

я думал, что есть уже какие-то модификации, которые лучше подходят для FPGA и менее итерационные...


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
alexkarnaukhov
сообщение May 15 2015, 14:23
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873



Ну вообще Ньютон как раз может и быть интересен. По крайней мере в алгоритме быстрого вычисления обратного корня именно он и используется. Кстати интересно, есть ли готовые корки, реализующие быстрый инверсный корень?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 11:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01519 секунд с 7
ELECTRONIX ©2004-2016