September 20th, 2021

QuatCore

atan1 "на четырёх умножениях" на ассемблере

Немножко подправил таблицу результатов для первого алгоритма. В этот раз вместо "правильных углов" 0°, 12°, 24° и т.д (те, которые я ХОТЕЛ взять для тестов) я взял те целочисленные значения X/Y, которые в действительности выступили входными данными для процедуры. Думал, что ошибка немного уменьшится, т.к часть ошибки была вызвана неточным представлением этих углов. На деле она возросла, как ни странно:



Только в 4 случаях из 15 получили все 16 бит верно, ещё в 8 случаях ошиблись на единичку младшего разряда, и в трёх случаях - на две единицы (в прошлый раз, как ни странно, такой случай был единственный).

В целом, поведение ожидаемое, когда производится 5 умножений комплексных чисел с хранением промежуточных чисел в 16-битном виде. Если каждое округление до 16 бит даёт нам случайную ошибку в 0,316 единицы младшего разряда (таково среднеквадратичное отклонение при равномерном распределении чисел перед округлением, один на корень из 10), и ошибки независимы друг от друга, то поскольку у нас 5 раз сохраняется по 2 числа (т.е действительная и мнимая часть), то ожидаем увеличения ошибки ещё в корень из 10 раз, до 1 единицы младшего разряда. Но распределение будет примерно Гауссовым, с дисперсией 1, и там вероятность, что ошибка будет [-0,5;0,5], т.е ни один бит не пострадает: 38%. Вероятность ошибки в 1 единицу младшего разряда (т.е [-1,5;-0,5] и [0,5;1,5]): 48%, в две единицы и выше: 14%. Худо-бедно похоже на то, что мы увидели.

Вообще, такая точность меня вполне устраивает, но "из спортивного интереса" хочу попробовать реализовать более быстрый и точный алгоритм.

Collapse )

Итого, 26 слов кода (1 лишнее из-за Hazard на одновременное чтение и запись памяти, транслятор вставляет NOP), или 52 байта. Не используется сегмент данных (только 3 значения хранятся на стеке). То есть, вышло чуточку компактнее предыдущей программы, которая занимала 29 слов кода и 15 слов данных.

Компилируется без проблем, вообще редчайшая вещь у нас - процедура совсем без ветвления! А испытывать начнём в следующем посте.
QuatCore

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

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


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


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

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

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

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

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

Collapse )

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

Наверное, пора успокоиться с арктангенсом и двинуть дальше. И макет довести уже до ума, и об его юстировке громко подумать...