BC/NW 2017 № 2 (31);7.1
АЛГОРИТМ БЫСТРОГО ВЫЧИСЛЕНИЯ ПОКАЗАТЕЛЬНЫХ ФУНКЦИЙ
Мачарадзе Г.Т., Морозова Е.А., Раскатова М.В.
Введение
При разработке систем реального времени бывают случаи, когда алгоритм не успевает завершиться за период обновления данных. В таких случаях необходимо искать способы оптимизации алгоритма обработки данных, чтобы ускорить время выполнения.
Примером такой системы могут быть 3D-системы. Для расчета таких параметров как освещение, отражение используется огромное количество нормалей поверхностей. Нормаль – вектор единичной длины, перпендикулярный данной поверхности. Чтобы нормализовать вектор (т.е. сделать единичной длины), необходимо вектор умножить на величину:. Ускорив операцию вычисления обратного корня, можно существенно ускорить обработку данных, поскольку извлечение квадратного корня занимает очень много машинного времени.
Алгоритм быстрого вычисления обратного квадратного корня был разработан в 1990-х годах компанией Silicon Graphics, а реализация впервые появилась в исходном коде компьютерной игры Quake III.
Целью данной статьи состоит в обобщении алгоритма для быстрого вычисления функций вида , а также в сравнении временных характеристик алгоритма быстрого вычисления с алгоритмом, использующим стандартные функции, что позволит сделать вывод о пригодности данного алгоритма на современных быстродействующих процессорах.
Некоторые сведения о числах с плавающей точкой
В ЭВМ вещественные числа представляются в формате IEEE754, согласно которому число представляется в виде бита знака, смещенного порядка и мантиссы. Для одинарной точности представления (соответствует типу float в языке C) справедливо следующее:
Формула для перехода из IEEE754 к десятичному формату:
(1)
Например, для десятичного числа 12.75 имеем:
.
Если интерпретировать порядок и мантиссу числа x как целые числа, то целочисленное представление числа x можно записать в виде
(2)
Математическое обоснование алгоритма
Пусть необходимо вычислить значение функции:
Прологарифмируем обе части равенства по основанию 2:
Заменим x и y, используя выражение (1):
Упрости выражение, раскрыв логарифм произведения:
(3)
Рассмотрим функцию . В нашем случае мантисса нормализована, т.е. справедливо неравенство: . На полуинтервале [0, 1) функция g(m) примерно ведет себя как линейная функция . Меняя параметр , мы можем улучшить точность приближения. дает лучшее приближение.
Таким образом, можно записать:
(4)
Преобразуем (3), используя (4):
Перейдем от e, m к E, M по равенствам, указанным в (1):
Умножим обе части равенства на L и перенесем все слагаемые, несвязанные с y в правую часть равенства:
Используя (2), получим:
(5)
Значение выбрано не просто так. Такой выбор позволяет заменить операцию умножения на сдвиг числа вправо или влево, в зависимости от знака p. Таким образом, целочисленную интерпретацию результата можно получить, сдвинув аргумент функции на k разрядов (вправо/влево) и прибавив константу. Данное приближение дает точность порядка 4%. Повысить точность можно с помощью метода Ньютона.
Рассчитаем значение константы из выражения (5) при :
Уточнение результата методом Ньютона
Формула для следующего приближения имеет следующий вид:
(6)
Применим данный метод для функции ;
Подставив производную в (6), получим формулу для второго приближения результата:
Данное уточнение повышает точность результата до 0.18%.
Реализация алгоритма вычисления обратного квадратного корня на языке C
inline float Q_Sqrt_Inverse(float x) {
const float half = 0.5f * x; //запоминаем половину для последующей аппроксимации
int y = * (int *)&x; //приводим к int
y = 0x5F3759DF - (y >> 1); //вычисляем первое приближение
x = * (float *)&y; //приводим к float
x = x * (1.5f - (half * x * x)); //аппроксимация метода Ньютона
return x;
}
В таблице 1 приведены полученные времена выполнения функции по сравнению с функциями, использующих стандартные математические функции sqrt и sqrtf.
Таблица 1
Время выполнения функций
|
sqrt |
sqrtf |
Q_Sqrt_Inverse |
Без уточнения результата |
0.170480 |
0.140246 |
0.060292 |
С уточнением результата |
0.170480 |
0.140246 |
0.083915 |
В таблице 2 приведены коэффициенты ускорения приведенного алгоритма по отношению к стандартным функциям sqrt и sqrtf.
Таблица 2
Коэффициенты ускорения алгоритма по отношению к стандартным функциям
|
Ускорение относительно sqrt |
Ускорение относительно sqrtf |
Без уточнения результата |
2.83 |
2.33 |
С уточнением результата |
2.03 |
1.67 |
Заключение
Анализируя полученные данные, можно с уверенностью заявить, что в настоящее время даже с учетом существования блоков FPU (Floating Point Unit), которые на аппаратном уровне реализуют операции с плавающей точкой, приведенный алгоритм все еще может использоваться по назначению. При точности 0.2% можно получить ускорение данной операции минимум на 50%.
Литература
1. Fast inverse square root – URL: https://en.wikipedia.org/wiki/Fast_inverse_square_root
2. А.А.Амосов, Ю.А.Дубинский, Н.В. Копченова – Вычислительные методы. Издательство Лань, 2014 год.