Да, показатели пропускной способности / задержки 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
double
. - person Peter Cordes   schedule 07.03.2019