Является ли float медленнее, чем double? 64-разрядная программа работает быстрее, чем 32-разрядная программа?

использует float введите медленнее, чем с помощью double тип?

Я слышал, что современные процессоры Intel и AMD могут выполнять вычисления с удвоениями быстрее, чем с поплавками.

насчет стандартных математических функций (sqrt, pow, log, sin, cos, etc.)? Вычисление их с одной точностью должно быть значительно быстрее, поскольку для этого требуется меньше операций с плавающей запятой. Например, single precision sqrt можно использовать более простую математическую формулу, чем double точность sqrt. Кроме того, я слышал, что стандартные математические функции быстрее в 64-битном режиме (при компиляции и запуске на 64-битной ОС). Каков окончательный ответ на этот вопрос?

6 ответов


классическая архитектура x86 использует блок с плавающей запятой (FPU) для выполнения вычислений с плавающей запятой. FPU выполняет все вычисления в своих внутренних регистрах, которые имеют 80-разрядную точность каждый. Каждый раз, когда вы пытаетесь работать с float или double переменная сначала загружается из памяти во внутренний регистр сопроцессора FPU. Это означает, что нет абсолютно никакой разницы в скорости на реальных расчетах, так как в любом случае расчеты выполняются с полной 80-битной точностью. Единственное что может отличаться-скорость загрузки значения из памяти и запись результата обратно в память. Естественно, на 32-битной платформе загрузка / хранение double по сравнению с float. На 64-разрядной платформе не должно быть никакой разницы.

современные архитектуры x86 поддерживают расширенные наборы инструкций (SSE / SSE2) с новыми инструкциями, которые могут выполнять те же вычисления с плавающей запятой без привлечения " старого" FPU инструкции. Однако, опять же, я не ожидал бы увидеть какую-либо разницу в скорости расчета для float и double. И поскольку эти современные платформы являются 64-битными, скорость загрузки / хранения также должна быть одинаковой.

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

Edit: (для адреса комментария @MSalters) То, что я сказал выше, относится к фундаментальным арифметическим операциям. Когда дело доходит до библиотечных функций, ответ будет зависеть от нескольких деталей реализации. Если набор инструкций с плавающей запятой платформы содержит инструкцию, которая реализует функциональность данной библиотечной функции, то то, что я сказал выше, обычно будет применяться и к этой функции (которая обычно включает такие функции, как sin, cos, sqrt). Для других функций, функциональность которых не сразу поддерживается в наборе инструкций FP, ситуация может оказаться значительно иной. Вполне возможно, что float версии таких функций могут быть реализованы более эффективно, чем их double версий.


ваш первый вопрос уже был ответ здесь на SO.

ваш второй вопрос полностью зависит от" размера " данных, с которыми вы работаете. Все сводится к низкоуровневой архитектуре системы и тому, как она обрабатывает большие значения. 64-битные данные в 32-битной системе потребуют 2 циклов для доступа к 2 регистрам. Те же данные в 64-битной системе должны принимать только 1 цикл для доступа к 1 регистру.

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


из некоторых исследований и эмпирических измерений, которые я сделал на Java:

также верно, что могут быть особые обстоятельства, в которых, например, проблемы с пропускной способностью памяти перевешивают " raw" время расчета.


" собственное " внутреннее представление с плавающей запятой в x86 FPU имеет ширину 80 бит. Это отличается от обоих float (32 бита) и double (64 бит). Каждый раз, когда значение перемещается в или из FPU, выполняется преобразование. Существует только одна инструкция FPU, которая выполняет грех операция, и она работает на внутреннем 80-битном представлении.

будет ли это преобразование быстрее float или double зависит от многих факторов, и должны быть измерены для данного приложения.


в то время как в большинстве систем double будет такой же скоростью, как float для отдельных значений, вы правы, что вычислительные функции, такие как sqrt, sin, etc. в одинарной точности должно быть намного быстрее, чем вычислять их с двойной точностью. В C99, вы можете использовать sqrtf, sinf, etc. функции, даже если ваши переменные double, и получить выгоду.

еще одна проблема, которую я видел, - это пропускная способность памяти (а также устройства хранения). Если у вас есть миллионы или миллиарды ценностей, с которыми приходится иметь дело,float почти наверняка будет вдвое быстрее, чем double поскольку все будет связано с памятью или io-связью. Это хороший повод использовать float как тип в массиве или на диске в некоторых случаях, но я бы не счел это хорошей причиной для использования float для переменных, с которыми вы делаете свои вычисления.


Это зависит от процессора. Если процессор имеет собственные инструкции двойной точности, обычно быстрее просто выполнить арифметику двойной точности, чем получить float, преобразовать его в double, выполнить арифметику двойной точности, а затем преобразовать его обратно в float.