Оптимальное деление компилятора для float

Я пишу функцию, которая влияет на ощущение элемента управления, и обнаружил, что деление на 15,9 было правильным. Мой естественный инстинкт состоит в том, чтобы изменить это на деление на 16, потому что это может быть оптимизировано компилятором для операции сдвига. Однако в этом случае значение является плавающим. Существуют ли оптимальные делители в вещественном делении?


person Ant    schedule 09.10.2012    source источник


Ответы (2)


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

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

person Henrik    schedule 09.10.2012
comment
Привет, Хенрик, я тоже об этом думал, но, поскольку это отбрасывает точность, я предполагаю, что компилятор этого не делает. - person Ant; 09.10.2012
comment
Пока у вас достаточно степеней двойки от недополнения, этот метод быстр и безопасен и не теряет точности (или отбрасывает точность, как вы выразились). Вопрос, конечно, в том, будет ли экспонента - при наименьшем ее значении - всегда достаточно большой, чтобы никогда не возникало потери значимости. - person Olof Forshell; 09.10.2012

Почему бы вместо этого не умножить на 0,0628930818? Если деление на 15,9 «примерно правильно», то умножение на обратное, хотя, возможно, и не совсем точное до последнего десятичного знака, все равно будет «примерно правильным». Оптимизирующий компилятор может даже сделать это автоматически, если используются некоторые "разрешающие математические" флаги (обычно это категорически недопустимо, так как это может привести к некоторой потере точности).

В любом случае, это точнее, чем деление на 16. И это не столько хак, сколько подделка битов экспоненты.

person Damon    schedule 09.10.2012
comment
Я не заинтересован в точности для этой работы. Я корректирую значение, когда пользователь поворачивает элемент управления, и это значение используется при расчете ускорения. Значение 15 или 17 работает так же хорошо. Я не думаю, что в процессоре есть большая разница между делением или умножением на обратное. Я также не заинтересован в том, чтобы вмешиваться во внутренности поплавка, мне просто интересно, выберу ли я хороший делитель, если я сэкономлю машинные циклы. - person Ant; 09.10.2012
comment
Что ж, умножение примерно такое же, как сложение или вычитание, обычно около 3-4 циклов на обычных процессорах для настольных ПК, тогда как деление составляет около 40 циклов. До сих пор, если идеальная точность не нужна (в любом случае она составляет 99,9%), но необходима экономия машинных циклов, я бы определенно умножил на обратную величину. С другой стороны, используя значение, например. 16.0 не имеет никаких преимуществ, потому что он не быстрее, используя математику с плавающей запятой, а все остальное (преобразование в и из фиксированной точки и сдвиг, изменение битов экспоненты и т. д.) намного, намного больше дорогой. - person Damon; 09.10.2012
comment
В SSE фальсификация показателей выполняется быстро, если это делается небезопасно. - person harold; 09.10.2012
comment
На самом деле, поскольку ни 15,9, ни его обратное число не могут быть представлены, дискуссия о точности сводится к тому, можно ли представить одно более точно, чем другое. В этом контексте 10-кратное время выполнения деления может быть решающим фактором для использования обратного и умножения. - person Olof Forshell; 09.10.2012