Пишу на асме под ATtiny2313A.
Затребовалось мне посчитать сумму квадратов трёхбайтных величин. Я, в принципе, знаю один способ умножения столбиком. В нём произведение строится в цикле по битам одно сомножителя прямо на месте другого сомножителя (с добавлением дополнительных байт для хранения результата, разумеется). Соответствующая процедура очень компактна по коду и использует минимально возможное число регистров процессора (1 на счётчик, n на один множитель и n*m на результат и другой множитель, размер которого m байт). Но она жутко медленная, а мне нужно считать квадраты в прерывании быстро.
Я знаю другой способ, с использованием таблиц квадратов. Кто не знаком с ним,
вот эту статью можно взять за отправную точку. Единственный минус подхода в статье заключается в том, что там используют сумму сомножителей, которая на один бит выходит за пределы размера сомножителей. Использование схемы ab = (a^2 + b^2 - (a - b)^2) / 2 более рационально в плане памяти, на мой взгляд. Особенно, если учесть, что таблица квадратов байта занимает в памяти 512 байт, что уже составляет 25% от всего ПЗУ моего МК.
Для построения программы составил себе шпаргалку:
Теперь вот думаю, как бы это по-лучше всё складывать. Квадраты будут суммироваться в кумулятивную сумму, которую логично хранить в оперативке. Так как обращение к ней медленнее, чем к регистрам, то логично формировать каждый байт-разряд суммы залпом, один раз читая его в начале и один раз записывая его в конце. Чтение таблицы квадратов из ПЗУ тоже не быстрая операция, поэтому логично читать каждый квадрат один раз и хранить результат в регистре, пока в нём есть потребность. Чтобы не таскать перенос от сложения по всей сумме от текущего разряда до самого старшего, логично собирать все переносы в отдельный регистр и добавлять к следующему разряду суммы, только когда приступим к его формированию. В итоге требуется очень много регистров МК, чтобы процедура работала шустро. Возможно, где-то быстродействием стоит пожертвовать, чтобы сократить расход регистров, они и в других частях программы используются.
Кто-нибудь делал что-нибудь подобное? Какие могут быть советы/рекомендации?
Добавлено after 2 hours 5 minutes 53 seconds:Как-то так выглядит умножение двух байт:
Для работы процедуры в памяти должна быть размещена вот такая таблица (фактически две таблицы: младший байтов квадратов и старших):
При этом важно, чтобы адрес таблицы в памяти был "круглым": заканчивался на 0x00 или 0x80.
- Вложения
-
- TribyteSquare.png
- (2.93 KiB) Скачиваний: 683