Использует ли double удвоение быстрее, чем float?

Двойные значения сохраняют более высокую точность и в два раза больше размера с плавающей запятой, но оптимизированы ли процессоры Intel для операций с плавающей запятой?

То есть являются ли двойные операции такими же быстрыми или быстрыми, как операции с плавающей запятой для +, -, * и /?

Изменяется ли ответ для 64-разрядных архитектур?

66
задан Peter Cordes 24 August 2018 в 04:05
поделиться

5 ответов

Не существует единого «процессора Intel», особенно с точки зрения того, какие операции оптимизированы по сравнению с другими !, но большинство из них на уровне процессора (особенно внутри FPU), таковы, что ответ на ваш вопрос:

такие же быстрые двойные операции или быстрее, чем операции с плавающей запятой для +, -, *, и /?

- «да» - в ЦП , за исключением деления и sqrt, которые несколько медленнее для double , чем для float . (Предполагая, что ваш компилятор использует SSE2 для скалярной математики FP, как и все компиляторы x86-64, и некоторые 32-разрядные компиляторы в зависимости от параметров. У устаревшего x87 нет разной ширины в регистрах, только в памяти (он преобразуется при загрузке / сохранении ), поэтому исторически даже sqrt и деление были такими же медленными для double ).

Например, Haswell имеет пропускную способность divsd , равную одному на 8–14 циклов (в зависимости от данных), но пропускную способность divss (единичный скаляр), равную одному на 7 циклов. x87 fdiv - это пропускная способность от 8 до 18 циклов. (Числа из https://agner.org/optimize/ . Задержка коррелирует с пропускной способностью для деления, но выше, чем числа пропускной способности.)

Версии float многих библиотечные функции, такие как logf (float) и sinf (float) , также будут быстрее , чем log (double) и sin (double) , потому что у них гораздо меньше битов точности, которые нужно исправить. Они могут использовать полиномиальные аппроксимации с меньшим количеством членов, чтобы получить полную точность для float vs. double


. Однако , занимая вдвое больше памяти для каждого числа, явно подразумевает большую нагрузку на кэш (ы) и дополнительная пропускная способность памяти для заполнения и вывода этих строк кэша из / в RAM; время, когда вы заботитесь о производительности операций с плавающей запятой, - это когда вы выполняете много таких операций, поэтому вопросы памяти и кеширования имеют решающее значение.

Ответ @ Ричарда указывает на то, что существуют и другие способы выполнения операций FP (инструкции SSE / SSE2; старый добрый MMX был только целочисленным), особенно подходящий для простых операций с большим количеством данных ( «SIMD», одна инструкция / несколько данных), где каждый векторный регистр может содержать 4 числа с плавающей запятой одинарной точности или только 2 числа двойной точности , так что этот эффект будет еще более заметным.

В конце концов, вам все-таки нужно выполнить тест, но я предполагаю, что для разумных (например, больших ;-) тестов вы найдете преимущество в использовании одинарной точности (при условии, конечно, что вам не нужны дополнительные биты точности! -).

73
ответ дан 24 November 2019 в 14:58
поделиться

Еще один момент, который следует учитывать, - если вы используете графический процессор (графическую карту). Я работаю над проектом, который требует большого количества вычислений, но нам не нужна проницательность, которую предлагает двойное. Мы используем карты GPU, чтобы ускорить обработку. Для графического процессора CUDA требуется специальный пакет для поддержки удвоения, а объем локальной ОЗУ на графическом процессоре довольно быстрый, но весьма скудный. В результате использование float также удваивает объем данных, которые мы можем хранить на графическом процессоре.

Еще один момент - это память. Поплавки занимают вдвое меньше оперативной памяти, чем двойные. Если вы имеете дело с ОЧЕНЬ большими наборами данных, это может быть действительно важным фактором. Если использование double означает, что вам нужно кешировать на диск, а не на чистый RAM, ваша разница будет огромной.

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

11
ответ дан 24 November 2019 в 14:58
поделиться

Если все вычисления с плавающей запятой выполняются внутри FPU, то нет, нет никакой разницы между вычислением double и вычислением float , потому что операции с плавающей запятой фактически выполняется с точностью 80 бит в стеке FPU. Записи стека FPU округляются соответствующим образом для преобразования 80-битного формата с плавающей запятой в формат с плавающей запятой double или float . Единственное различие в скорости - перемещение sizeof (double) байтов в / из RAM по сравнению с sizeof (float) байтов.

Однако, если у вас есть векторизуемое вычисление, вы можете использовать расширения SSE для выполнения четырех вычислений float одновременно с двумя вычислениями double . Следовательно, грамотное использование инструкций SSE и регистров XMM может обеспечить более высокую пропускную способность для вычислений, которые используют только float s.

24
ответ дан 24 November 2019 в 14:58
поделиться

Единственный действительно полезный ответ: только вы можете сказать. Вам необходимо сравнить свои сценарии. Небольшие изменения в инструкциях и шаблонах памяти могут иметь значительное влияние.

Безусловно, будет иметь значение, используете ли вы оборудование типа FPU или SSE (первое выполняет всю свою работу с 80-битной расширенной точностью, поэтому double будет ближе; позже будет изначально 32-битный, то есть с плавающей точкой).

Обновление: s / MMX / SSE /, как указано в другом ответе.

7
ответ дан 24 November 2019 в 14:58
поделиться

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

2
ответ дан 24 November 2019 в 14:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: