Оптимизация SQRT Пифагора ()

После некоторых тестов измерения задержки я понял, что мне нужно оптимизировать вычисление треугольника Пифагора на встроенном процессоре с довольно медленным FPU.

Проблема состоит в том, что если эти вычисления происходят, они приходят в числа, и это портит сроки. Я не могу уменьшить абсолютное количество расчетов. Но как-то им нужно быстрее … хотя бы в 5 раз.: — /

В настоящее время я думаю о предварительной обработке этих вычислений, поскольку входной диапазон различных значений как-то ограничен примерно 300-500 перестановками, и интерполяции между двумя записями таблицы должно быть достаточно. Но мне также было интересно, если бы с помощью некоторых условий проблемы можно было бы также ускорить этот код:

float h = 0.f, v=0.f;
/// ...
float const d = std::sqrt( (h*h) + (v*v) );

Это я еще не использовал:

  1. Точность результата d очень ограничено не более, так как требуется 3 дробных цифры
  2. Ноги треугольника (h, v) всегда имеют соотношение сторон 4: 3 или 16: 9.

Я не знаю, доступны ли какие-либо целочисленные вычисления с фиксированной точкой для квадратного корня или можно заменить функцию на одну с меньшей точностью или каким-либо образом использовать соотношение сторон.

Есть идеи?

Спасибо!

3

Решение

Если вы знаете, что соотношение составляет 16: 9, вы можете сделать небольшую алгебру:

h = 16*x
v = 9*x
x = h/16
sqrt((h*h) + (v*v)) = sqrt((16*16*x*x) + (9*9*x*x))
= sqrt((16*16+9*9)*x*x)
= sqrt(16*16+9*9)*x
= sqrt(16*16+9*9)*h/16
= sqrt(16*16+9*9)/16 * h

предварительно вычислить sqrt(16*16+9*9)/16:

static float const multiplier = std::sqrt(16*16+9*9)/16.0;

и использовать

float const d = multiplier*h;
5

Другие решения

Я не знаю, сколько у вас ОЗУ / ПЗУ в этой встроенной системе, но если у вас есть какие-то, вам, возможно, стоит рассчитать квадраты и корни с квадратными корнями. Это предполагает, что ваш встроенный ЦП имеет возможность кэширования и / или доступ к ОЗУ / ПЗУ быстрее, чем вычисления с плавающей запятой.

Тем не менее, существуют численные методы для вычисления квадратного корня, но я не уверен, что на практике они будут быстрее, чем вызов sqrt, независимо от того, насколько медленными.

1

Вы знаете библиотеку Boost :: math?
Здесь вы можете найти некоторые интересные вещи для корней: http://www.boost.org/doc/libs/1_54_0/libs/math/doc/html/math_toolkit/internals1/roots.html

1
По вопросам рекламы [email protected]