Битовая манипуляция для замены оператора IF и повышения производительности

0

Я могу заменить следующий оператор IF:

if(condition){
    x += y;
}

с:

x = x + ((y - x) * (condition));

для удаления ветвления.

Есть ли способ избежать вышеупомянутого умножения и заменить его побитовой манипуляцией, чтобы сделать его быстрее?

  • 1
    Держись, это не кажется правильным. Разве это не должно быть x + (y * (condition)) ?
  • 6
    Большинство современных процессоров обеспечивают условное присвоение без ответвлений. Удостоверьтесь, что вы измеряете «оптимизацию», с которой вы столкнулись, чтобы убедиться, что вы не замедлили процесс.
Показать ещё 5 комментариев
Теги:
optimization
performance
bit-manipulation

6 ответов

10

Не делайте этого без измерения вашего приложения с ожидаемым использованием.

Почему нет.

Современные компиляторы уже могут обнаружить и преобразовать такие шаблоны в условные движения.

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

Как сказано: Не делайте этого без измерения вашего приложения с ожидаемым использованием. Не проверяйте на произвольных тестах, которые в большинстве случаев приводят к ошибочным (и, следовательно, дорогостоящим) результатам. И, конечно, предпочитают оптимизацию алгоритмов и архитектуры вместо таких микрооптимизаций; поддерживающий код, поддерживаемый, обычно дешевле в долгосрочной перспективе; не создавайте свой бизнес по неопределенному поведению и высокоспециализированному коду:

Изображение 174551

Также.

Вам достаточно C или C++, чтобы проверить правильность вашей "оптимизации"? Вы считали неподписанное переполнение и неопределенное поведение по поводу переполнения подписей? Тип рекламных акций?

Я думаю, что ответ отрицательный, потому что вы просите о помощи, но не понимаете, что типы, используемые в вашем примере, имеют решающее значение, но не упоминаются.

8

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

3
if(condition){
    x += y;
}

является

if(condition){
    x =x+ y;
}

так что вы можете написать это как,

x = x + ((y) * (condition));

только если условие равно 0 или 1. если условие может быть любым другим значением, то это не будет работать.

x = x + ((y - x) * (condition));

неверно, даже если условие приводит только к 0 или 1 поскольку оно эквивалентно,

  if(condition){
        x=y;
    }
2

Не уверен, что вы можете бить целое число размножаться. На некоторых процессорах требуется один такт.

Предполагая условие 0/1:

x+= condition * y;

В качестве альтернативы:

x+= (- condition) & y;
1

Прежде чем делать какие-либо попытки оценить, вы должны добавлять типы для каждой переменной. У людей могут быть разные предположения. Также мой совет не будет этого делать. Даже если вы доберетесь до этого, это станет кошмаром для поддержания.

-4

Сделайте это один бит, сдвиньте его до знакового бита, а затем сдвиньте его с расширением знака до конца, и вы получите либо all-ones, либо all-zeroes.

x + (( y -x) & (((!!condition)<<31)>>31)

Это зависит от платформы.

  • 2
    Узкоспециализированный, нечитаемый, неопределенный, сильно зависимый от платформы. Полностью не хватает объяснения.
  • 1
    "сдвинуть его до знака бита" Это неопределенное поведение.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню