Как я могу сравнить производительность деления log () и fp в C ++? - PullRequest
13 голосов
/ 18 мая 2010

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

Однако в определенный момент в моем алгоритме мне нужно разделить стандартное значение double на значение integer, а затем сделать *= на значение на основе журнала. Я перегрузил оператор *= для моего класса, основанного на журнале, и значение правой части сначала преобразуется в значение на основе журнала, выполнив log(), а затем добавляется к значению левой стороны. Таким образом, фактически выполняемые операции - это деление с плавающей запятой, log() и суммирование с плавающей запятой.

Мой вопрос, будет ли быстрее сначала преобразовать знаменатель в логическое значение, которое заменит деление с плавающей запятой вычитанием с плавающей запятой, приводя к следующей цепочке операций: дважды log(), с плавающей запятой вычитание точек, суммирование с плавающей точкой.

В конце концов, все сводится к тому, быстрее или медленнее деление с плавающей точкой, чем log(). Я подозреваю, что распространенным ответом будет то, что это зависит от компилятора и архитектуры, поэтому я скажу, что я использую gcc 4.2 от Apple на darwin 10.3.0. Тем не менее, я надеюсь получить ответ с общим замечанием о скорости этих двух операторов и / или идеей о том, как измерить разницу самостоятельно, поскольку здесь может быть что-то еще, например, выполнение конструкторов, которые выполняют преобразование типов и т. д.

Ура!

Ответы [ 4 ]

12 голосов
/ 18 мая 2010

Делите ли вы на одно целое число несколько раз? Если это так, вы можете вместо этого умножить на 1./yourInteger и делить только один раз. Это было бы быстрее, чем любой другой, если это возможно.

Что касается вашего фактического вопроса, это зависит не только от компилятора и архитектуры, но также от микро-архитектуры и данных.

На вашей конкретной платформе (darwin / x86) для текущего аппаратного обеспечения i5 / i7: ~ 24 цикла для деления (1), ~ 35 циклов для log( ) (2). Однако, поскольку разделение использует только один интервал диспетчеризации команд, механизм переупорядочения аппаратных средств может выполнять другие полезные вычисления, пока разделение выполняется; В отличие от этого, log( ) реализовано в программном обеспечении, поэтому у процессора меньше возможностей для поднятия других вычислений в латентность логарифма. Это означает, что на практике деление часто будет намного быстрее.

1) Из руководства по оптимизации Intel

2) Измеряется путем вызова log( ) в тесной петле и использования mach_absolute_time( ) для получения времени на стене.

5 голосов
/ 18 мая 2010

В архитектуре x86 логарифмы занимают значительно больше времени, чем деления: 85 циклов (пропускная способность) для FYL2X по сравнению с 40 циклами для FDIV . Я был бы удивлен, если бы другие архитектуры сильно отличались. Перейти с делением с плавающей запятой.

1 голос
/ 18 мая 2010

Я почти уверен, что вычисление лога по любому алгоритму будет стоить дороже, чем даже деление FP.

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

1 голос
/ 18 мая 2010

Основная проблема с делением состоит в том, что, хотя на большинстве современных процессоров это одна инструкция, обычно она имеет высокий latency (31 цикл на PowerPC - не уверен, что на x86). Некоторые из этих задержек могут быть скрыты, если у вас есть другие независимые инструкции, которые могут быть изданы одновременно с разделением. Таким образом, ответ будет зависеть в некоторой степени от того, какой тип инструкции и зависимости у вас есть в цикле, который содержит ваш разрыв (не говоря уже о том, какой процессор вы используете).

Сказав это, я чувствую, что в большинстве архитектур деление будет быстрее, чем функция журнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...