Какой самый быстрый способ получить абсолютное значение числа - PullRequest
37 голосов
/ 20 марта 2009

Какой самый быстрый способ реализовать операцию, которая возвращает абсолютное значение числа?

x=root(x²)

или

if !isPositive(x):
    x=x*(-1)

На самом деле этот вопрос можно перевести как, как быстро if (и почему, пожалуйста).

Мои профессора по программированию в колледже всегда говорили мне избегать if s, потому что они чрезвычайно медленные, но я всегда забывал спросить, как медленно и почему. Кто-нибудь здесь знает?

Ответы [ 13 ]

0 голосов
/ 22 ноября 2016

Я занимаюсь программированием ретро-графики на C для 8088/8086, и вызов abs() занимает много времени, поэтому я заменил его на:

/* assuming 'i' is int; this WILL NOT WORK on floating point */
if (i < 0) {
    i = ~i + 1;
}

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

0 голосов
/ 18 марта 2015

То, что быстрее, очень зависит от того, на какой компилятор и на какой процессор вы ориентируетесь. На большинстве процессоров и на всех компиляторах x = (x> = 0)? х: -x; это самый быстрый способ получить абсолютное значение, но на самом деле, часто стандартные функции уже предлагают это решение (например, fabs ()). Он компилируется в сравнение с последующей инструкцией условного присваивания (CMOV), а не в условный переход. Однако на некоторых платформах этой инструкции нет. Хотя компилятор Intel (но не Microsoft или GCC) автоматически преобразует if () в условное присвоение и даже попытается оптимизировать циклы (если это возможно).

Код ветвления в целом медленнее, чем условное присвоение, если ЦП использует статистическое прогнозирование. if () может быть медленнее в среднем, если операция повторяется несколько раз, а результат условия постоянно меняется. Процессоры, такие как Intel, начнут вычислять обе ветви и сбросят недопустимую, в случае больших тел if () или большого количества циклов, которые могут быть критическими.

sqr () и sqrt () на современных процессорах Intel представляют собой одну встроенную инструкцию и не являются медленными, но они неточны, и загрузка регистров также потребует времени.

Схожий вопрос: Почему медленная инструкция ветвления ЦП?

Скорее всего, профессор хотел, чтобы студент проводил исследования по этому вопросу, это полупровокационный вопрос \ задача, которая принесет пользу только в том случае, если студент научится думать самостоятельно и искать дополнительные источники.

0 голосов
/ 21 октября 2014

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

...