переключение fpu на одинарную точность

Я читал, что на более старых fpu за пару лет до fpu при переключении в режим одинарной точности деления и sqr делались в два раза быстрее, чем в обычном режиме.

(проверьте источник http://stereopsis.com/FPU.html)

Это все еще так, и такое переключение может ускорить некоторые циклы, создавая внутри много плавающего кода?

Второй вопрос связан с тем, могу ли я свободно играть с точностью FPU в моем коде при выполнении системных (winapi) вызовов, например, То же самое с режимом округления fpu и со стороны системы, Может ли api также испортить мои настройки?


person grunge fightr    schedule 03.10.2012    source источник
comment
Функция поиска _controlfp в MSDN   -  person Marat Dukhan    schedule 03.10.2012
comment
Если вы делаете это для повышения производительности, почему бы просто не использовать SSE? Я не могу себе представить, чтобы серьезно относиться к производительности в системе, достаточно старой, чтобы не иметь SSE.   -  person Mysticial    schedule 03.10.2012
comment
Я повторяю комментарий Mysticial с несколько иной точки зрения. FPU на основе исторического стека, который работал с 80-битными расширенными числами с плавающей запятой, действительно мог быть ограничен 64-битными или 32-битными мантиссами. В настоящее время у нас есть набор инструкций SSE2 с инструкциями, которые работают непосредственно с числами одинарной или двойной точности. Ссылке, которую вы читаете, 12 лет. Нет никаких оснований предполагать, что еще быстрее возиться со старыми инструкциями FPU для ограничения точности. Даже если это так, уверены ли вы, что код, который вы собираетесь ускорить, не использует инструкции SSE2?   -  person Pascal Cuoq    schedule 03.10.2012
comment
Что делать, если я просто хочу получить максимум spped от fpu, просто чтобы знать, или не переписывать большой код с плавающей запятой fpu в sse (что займет пару дней, когда переключение на одинарную точность не займет много времени)   -  person grunge fightr    schedule 03.10.2012
comment
@PascalCuoq: 80-битный x87 float равен 64-битной ширине мантиссы: P Ограничение до 64-битной общей ширины = ограничение до 53-битной точности мантиссы = округление каждого результата до IEEE binary64 double.   -  person Peter Cordes    schedule 07.03.2019
comment
@PeterCordes. Вы правы, здесь должно быть написано: «Значения ширины, эквивалентной IEEE 754 binary64 или binary32» или что-то в этом роде, но сейчас это слишком старо, чтобы исправлять. :)   -  person Pascal Cuoq    schedule 07.03.2019


Ответы (2)


Да, показатели пропускной способности / задержки Agner Fog полностью согласуются с уменьшением точности x87 и ускорением в худшем случае.

Это также имеет смысл, учитывая то, как работает современное оборудование div / sqrt, с использованием делителя Radix-16 или Radix-1024, который итеративно вычисляет больше бит результата, поэтому меньшее количество правильных битов означает, что вы можете остановиться раньше. (Как sqrt () GCC работает после компиляции? Какой метод root используется? Newton-Raphson? и Алгоритм целочисленного деления процессоров Intel x86)

Это также имеет смысл, учитывая, что x87 fdiv и SSE1 divss работают на одном и том же оборудовании, причем divss имеет одинаковый лучший случай (округленные делители), но лучший худший случай. Биты точности x87, по-видимому, управляют делителем HW точно так же, как divss или divsd.

подробности ниже


Да, x87 может быть ограничен до 64- или 32-битной общей ширины (double или float) по сравнению со стандартными 80-битными. И да, это немного ускоряет fsqrt и fdiv худшие случаи, чтобы быть примерно такой же скоростью, как скалярный SSE / SSE2 той же точности (sqrtss = скалярный одиночный / sqrtsd = скалярный двойной). Больше ничего не работает быстрее или медленнее.

Это не делает x87 быстрее, чем SSE, так что на данный момент это в основном любопытство, связанное с историей процессора.

Очевидно, DirectX действительно (раньше?) Устанавливает точность x87 на 24-битную мантиссу (float), а запуск CRT MSVC используется для установки 53-битной мантиссы (double). См. https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/. Но историческая странность Microsoft - исключение; другие инструментальные системы / ОС не возятся с x87.

В таблицах инструкций Agner Fog не упоминается точность x87 для процессоров Sandybridge или новее. Это может означать, что это больше не помогает, или (я думаю), что Агнер решил, что об этом не стоит упоминать. В его таблицах SnB и более новых нет никаких сносок, так что я думаю, что это объяснение. Насколько я знаю, делитель SnB не сильно отличается от NHM.

Для Нехалема:

  • fdiv 7–27 циклов, задержка = пропускная способность (без конвейерной обработки), со сноской, в которой говорится, что круглые делители или низкая точность дают низкие значения.

  • _15 _ / _ 16_ 7-22 цикла, задержка = пропускная способность.

  • _17 _ / _ 18_ 7–14 циклов, задержка = пропускная способность.

Таким образом, производительность в лучшем случае (делитель занимает 7 циклов) одинакова для всех форм, а в худшем случае, чем хуже, тем больше возможно бит мантиссы.

Мы знаем, что HW делителя является итеративным и должен продолжать работать дольше, чтобы вычислить большее количество бит, поэтому на 100% правдоподобно, что установка точности x87 на 24 или 53 бит помогает производительности точно таким же образом что при использовании divss. В любом случае они используют одну и ту же аппаратную исполнительную единицу.

IvyBridge наконец-то сконфигурировал делитель FP. Haswell не внес никаких серьезных изменений по сравнению с IvB в числа div. Это номера HSW:

  • fdiv Задержка 10-24c, пропускная способность 8-18c
  • divsd / divpd xmm: задержка 10-20c, пропускная способность 8-14c
  • divss / divps xmm: задержка 10-13c, пропускная способность 7c (фиксированная задержка удобна для планировщика)

См. Также Деление с плавающей запятой против умножения с плавающей запятой, где Я собрал данные Агнера Фога для последних процессоров Intel, включая 256-битные векторы YMM. Я оставил там x87, потому что он в принципе не имеет отношения к высокой производительности.


Обычно вы просто используете SSE1, потому что он, как правило, быстрее (пропускная способность внешнего интерфейса не тратится на fxch и fld копии регистров благодаря плоскому набору регистров и инструкциям с двумя операндами вместо стека). И возможность использовать SIMD для некоторых случаев (обычно 4x float sqrt дает то же время, что и 1) делает его огромным преимуществом по сравнению с 32-битным FPU x87.

Большинство математических инструкций SSE имеют такую ​​же пропускную способность и задержку, что и их аналоги x87, но x87 имеет больше накладных расходов.

Если вам нужно создать 32-битный двоичный файл, совместимый с древними процессорами, даже без SSE1, да, вы можете уменьшить точность x87 до 24-бит, если производительность fdiv и fsqrt важно для вашего кода. (Возможно, также ускорит некоторые микрокодированные инструкции x87, такие как fsin и fyl2x, IDK.)

Или, если уменьшение точности до float слишком радикально, тогда вы смотрите на SSE2 для double математики в регистрах XMM. Это базовый уровень для x86-64, поэтому снова стоит задуматься, только если вам по какой-то причине необходимо создать 32-битный двоичный файл. Новейший процессор без него - Athlon XP. (Если вы не считаете такие вещи, как текущий Geode.)


То же самое с режимом округления fpu и со стороны системы, может ли api также испортить мои настройки?

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

Если бы кто-нибудь когда-либо мог оправдать это, кто-то сделал бы это для производительности C, который использует (int)float без инструкций SSE convert-with-truncation (или SSE3 fisttp для версии x87), чтобы избежать необходимости устанавливать режим округления x87 на усечение (в сторону 0), а затем восстанавливать его каждый раз, когда значение FP преобразуется в целое число.

Большинство компиляторов предполагают округление до ближайшего при оптимизации.

person Peter Cordes    schedule 07.03.2019

Насколько я понимаю, влияние точности на скорость устаревшего FPU x86 в значительной степени закончилось с i486. Хотя это была обычная оптимизация еще 8087 дней.

person Brian Knoblauch    schedule 03.10.2012
comment
похоже, что однажды мне придется измерить это сам: / лично я думаю, что это все еще может дать ускорение для div - person grunge fightr; 03.10.2012