nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Быстрее, меньше, точнее!

Начинаем тестировать новую процедуру арктангенса. Сначала на симуляции. Получаем дамп памяти:


Переписываем числа в таблицу:


Первая половина таблицы очень многообещающая: ошибка не более 1 единицы младшего разряда, да и та случается в 6 случаях из 16, это уже прогресс по сравнению с предыдущим алгоритмом!

Но вот со второй половиной какая-то фигня: мы каким-то образом перепутали знак! Причём если посмотреть 4 варианта знака для (32052;6813):

(32052;6813)
(-32052;6813)
(-32052;-6813)
(32052;-6813)

то окажется: только когда оба числа положительных, мы выставили знак "+", во всех остальных случаях был знак "-".

Кто бы мог подумать: ассемблерная функция не заработала правильно с первого раза! Что ж, надо разобраться.


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


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

atan1 proc
137  F3A4      [SP++]  ijk
138  A202      k       0
139  80C0      Acc     [X+1]
13A  90C8      MUL     [X+k]
13B  A381      Inv     S
13C  84C8      ABS     [X+k]
13D  86C0      ABSA    [X+1]
13E  FC82      [SP]    UAC ;в [SP] лежит x'
13F  8900      NOP  0 ;AUTOMATICALLY INSERTED BY TRANSLATOR TO PREVENT HAZARD
140  84C0      ABS     [X+1]
141  87C8      ABSS    [X+k]
142  F080      [SP+1]  Acc ;в [SP+1] лежит y'
143  9C80      SQRD2   Acc ;результат чуть точнее за счёт байпаса
144  8A5A      C       -1951
145  9080      MUL     Acc ;-1951y'^2/2
146  8A5B      C       5445


Заносим в стек содержимое регистров, 0x7400. Красивое число, это ж считай 155ЛА3, она же латрёшка! Это из-за того, что Inv=0, k=29, i=j=0. Собираешь всё это вместе, {Inv,k,i,k} - оно и выходит. (Inv - однобитный, остальные 5-битные)

Далее опять компилятор "выпендривается": его просишь k=0, а он туда суёт 0x00C0. Ну да, поскольку k 5-битный, так оно и выйдет. Просто компилятор последовательно перебирал уже существующие значения, какие сюда подойдут - и уже это подошло. Хотя "чистый ноль" очевидно тоже есть, куда же без него...

Аааа, Семён Семёныч, я уже сам ошибку увидел... Нахрена я аккумулятор инициализирую, если должен в регистр C положить один из множителей! Команда MUL вообще аккумулятор "затирает" начисто.

Ладно, меняем Acc на C в этой команде и снова смотрим дамп:


Вот это уже правильно: через 180 градусов значения полностью повторяются.

Ешё, раз уж симуляцию запустил, посмотрю, сколько времени занимает выполнение процедуры atan1: 5,4 мкс, или 135 тактов. В 4 раза быстрее предыдущего алгоритма!

Но нельзя ли ещё поднять точность? Я построил график ошибки для целочисленных коэффициентов, которые у нас получились:


Максимальная ошибка: 5,83 угловой секунды. Это в предположении, что все вычисления происходят с абсолютной точностью, но с использованием этих целочисленных коэффициентов. Но на эту методическую ошибку ещё накладывается ошибка округления. К примеру, правильное число должно было получиться 5,23. Но из-за небольшой ошибки вышло 5,51. Вроде ошибка меньше, чем половина единицы младшего разряда, а даже такой добавочки хватает, чтобы мы не в ту сторону "шатнулись".

В общем-то, ситуация как с умножением двух 16-битных чисел с округлением до 16 бит: чтобы НИ РАЗУ не ошибиться в результате, нужен 31-битный аккумулятор, а если с "округлением банкира" - то вообще честный 32-битный.

Вот и здесь "последняя миля", обеспечить, чтобы самый младший разряд также стал точным - очень сложно! Есть пути: более точно представить коэффициенты, а потом перед прибавлением π/4 поделить результат на 2, а там и новые слагаемые добавить. Но думаю, игра не стоит свеч.


Итак: быстрее в 4 раза, меньше на 36 байт, точнее вдвое (максимальная ошибка в 1 единицу младшего разряда вместо 2). Чебышёв на пару с Ремезом рулят!

Наверное, пора успокоиться с арктангенсом и двинуть дальше. И макет довести уже до ума, и об его юстировке громко подумать...
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

  • Великая Октябрьская резня бензопилой

    Сегодня прокатился прочистить Абрамцевскую просеку. Как обычно, с приключениями. Выезжал на велосипеде, а вернулся на самокате. Первый раз по этим…

  • Очередная несуразность в единицах измерения

    Когда-то я написал программу PhysUnitCalc - калькулятор, умеющий работать с размерностями. Мне казалось, что я наступил уже на все грабли, которые…

  • Big Data, чтоб их... (3)

    "В предыдущих сериях": мой прибор выдаёт 6 значений: 3 координаты и 3 угла, т.е все 6 степеней свободы твёрдого тела. Причём ошибки измерения этих 6…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments