Можно ли свернуть значительно более быструю версию sqrt
в приложении, которое я профилирую, я обнаружил, что в некоторых сценариях эта функция может занять более 10% от общего времени выполнения.
Я видел обсуждение на протяжении многих лет более быстрых реализаций sqrt с использованием подлого обмана с плавающей запятой, но я не знаю, устарели ли такие вещи на современных процессорах.
используется компилятор MSVC++ 2008 Для справки... хотя я бы предположил, что sqrt не собирается добавлять много накладных расходов.
см. Также здесь для подобных обсуждение на modf.
EDIT: для справки,этой является одним широко используемым методом, но на самом деле это намного быстрее? Сколько циклов SQRT в любом случае в эти дни?
4 ответов
Да, это возможно даже без плутовства:
1) жертвуйте точностью для скорости: алгоритм sqrt итеративен, повторно реализует с меньшим количеством итераций.
2) таблицы поиска: либо только для начальной точки итерации, либо в сочетании с интерполяцией, чтобы получить вас там.
3) кэширование: вы всегда sqrting тот же ограниченный набор значений? если это так, кэширование может работать хорошо. Я нашел это полезным в графических приложениях, где то же самое вещь рассчитывается для множества фигур одинакового размера, поэтому результаты могут быть с пользой кэшированы.
здесь есть отличная таблица сравнения: http://assemblyrequired.crashworks.org/timing-square-root/
короче говоря, ssqrts SSE2 примерно в 2 раза быстрее, чем FPU fsqrt, а приближение + итерация примерно в 4 раза быстрее, чем это (8X в целом).
кроме того, если вы пытаетесь взять sqrt с одной точностью, убедитесь, что это на самом деле то, что вы получаете. Я слышал по крайней мере об одном компиляторе, который преобразует аргумент float в double, call двойная точность sqrt, а затем преобразовать обратно в float.
вы, скорее всего, получите больше улучшений скорости, изменив свой алгоритмы чем изменяя их реализации: попробуй позвонить sqrt()
меньше, вместо того, чтобы делать звонки быстрее. (И если вы думаете, что это невозможно - улучшения для sqrt()
вы упоминаете только то, что: улучшения алгоритм используется для вычисления квадратного корня.)
поскольку он используется очень часто, вполне вероятно, что ваша стандартная библиотека реализация sqrt()
почти оптимально для общего случая. Если у вас нет ограниченного домена (например, если вам нужно меньше точности), где алгоритм может принимать некоторые ярлыки, очень маловероятно, что кто-то придумает реализацию, которая быстрее.
обратите внимание, что, поскольку эта функция использует 10% вашего времени выполнения, даже если вам удастся придумать реализацию, которая занимает только 75% времени std::sqrt()
, Это все равно приведет только ваше время выполнения вниз 2,5%. Для большинства приложений пользователи даже не заметят этого, за исключением случаев, когда они используют часы для измерения.
насколько точно вам нужен ваш sqrt
быть? Вы можете получить разумные приближения очень быстро: см. Quake3 отлично инверсный квадратный корень функция для вдохновения (обратите внимание, что код GPL'Ed, поэтому вы не можете интегрировать его напрямую).