Вы сказали, что все значения являются динамическими, что имеет значение. Для конкретных значений 5 * j / 4
целочисленные операции будут невероятно быстрыми, потому что в худшем случае компилятор оптимизирует их до двух сдвигов и одного сложения, плюс некоторые возни, чтобы справиться с возможностью того, что j
отрицательное. Если ЦП может работать лучше (целочисленное умножение за один цикл или что-то еще), то компилятор обычно знает об этом. Ограничения возможностей компиляторов по оптимизации такого рода вещей в основном возникают, когда вы компилируете для большого семейства процессоров (например, генерируете код ARM с наименьшим общим знаменателем), где компилятор на самом деле мало что знает о оборудования и, следовательно, не всегда может сделать правильный выбор.
Я предполагаю, что если a
и b
фиксированы на какое-то время (но неизвестны во время компиляции), то возможно, что вычисление k = double(a) / b
один раз, а затем int(k * x)
для множества различных значений x
, может быть быстрее, чем вычисление a * x / b
для множества различных значений x
. Я бы не стал на это рассчитывать.
Если все значения каждый раз меняются, маловероятно, что деление с плавающей запятой для вычисления 1.25
с последующим умножением с плавающей запятой будет быстрее, чем целочисленное умножение с последующим целочисленным делением. Но вы никогда не знаете, проверьте это.
На современных процессорах невозможно дать простые относительные тайминги для этого, это действительно сильно зависит от окружающего кода. Основные затраты в вашем коде часто связаны не с «настоящими» операциями: это «невидимые» вещи, такие как зависание конвейеров инструкций из-за зависимостей, сброс регистров в стек или накладные расходы на вызовы функций. Независимо от того, может ли функция, которая выполняет эту работу, быть встроенной, может быть больше разницы, чем то, как функция на самом деле это делает. Что касается окончательных заявлений о производительности, вы можете в основном тестировать реальный код или заткнуться. Но есть вероятность, что если ваши значения начинаются как целые числа, выполнение над ними целочисленных операций будет быстрее, чем преобразование в double
и выполнение аналогичного количества double
операций.
person
Steve Jessop
schedule
27.09.2013
a
,b
иc
и вы хотите вычислитьa * b / c
, вам следует написатьint compute(int a, int b, int c) { return a * b / c; }
. Я сомневаюсь, что вы могли бы сделать лучше. - person Kerrek SB   schedule 28.09.20131.25
на самом деле являетсяdouble
, а неfloat
. - person LihO   schedule 28.09.2013static_cast<double>(a) / static_cast<double>(c)
, тогда вам нужно преобразоватьb
в число с плавающей запятой, умножить, а затем округлить в обратном направлении, используя округление, предписанное C++, все и любое из которых вряд ли будет быть быстрее, чем две целочисленные операции. - person Kerrek SB   schedule 28.09.20135/4
и1.25
. Если бы числитель и знаменатель не были константами времени компиляции, как узнать, что нужно умножать на1.25
? (без фактического разделения, которого вы пытаетесь избежать) - person Mysticial   schedule 28.09.2013