Я могу заменить следующий оператор IF:
if(condition){
x += y;
}
с:
x = x + ((y - x) * (condition));
для удаления ветвления.
Есть ли способ избежать вышеупомянутого умножения и заменить его побитовой манипуляцией, чтобы сделать его быстрее?
Не делайте этого без измерения вашего приложения с ожидаемым использованием.
Современные компиляторы уже могут обнаружить и преобразовать такие шаблоны в условные движения.
Современные процессоры спекулятивно запускают код "до времени", который может быть быстрее, чем сложное битовое выражение; Кроме того, существует буфер целевого буфера, который запоминает решения в локальных циклах, а затем спекулятивно запускает ваш код раньше времени на основе BTB.
Как сказано: Не делайте этого без измерения вашего приложения с ожидаемым использованием. Не проверяйте на произвольных тестах, которые в большинстве случаев приводят к ошибочным (и, следовательно, дорогостоящим) результатам. И, конечно, предпочитают оптимизацию алгоритмов и архитектуры вместо таких микрооптимизаций; поддерживающий код, поддерживаемый, обычно дешевле в долгосрочной перспективе; не создавайте свой бизнес по неопределенному поведению и высокоспециализированному коду:
Вам достаточно C или C++, чтобы проверить правильность вашей "оптимизации"? Вы считали неподписанное переполнение и неопределенное поведение по поводу переполнения подписей? Тип рекламных акций?
Я думаю, что ответ отрицательный, потому что вы просите о помощи, но не понимаете, что типы, используемые в вашем примере, имеют решающее значение, но не упоминаются.
Такая оптимизация практически никогда не улучшит вашу производительность. Компилятор улучшает работу над оптимизацией кода, чем вы можете сделать с такими дешевыми трюками. Также в этом случае вы фактически добавляете больше сложности в код, делая его менее эффективным. Умножение всегда необходимо выполнить, и будет выполнено добавление.
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;
}
Не уверен, что вы можете бить целое число размножаться. На некоторых процессорах требуется один такт.
Предполагая условие 0/1:
x+= condition * y;
В качестве альтернативы:
x+= (- condition) & y;
Прежде чем делать какие-либо попытки оценить, вы должны добавлять типы для каждой переменной. У людей могут быть разные предположения. Также мой совет не будет этого делать. Даже если вы доберетесь до этого, это станет кошмаром для поддержания.
Сделайте это один бит, сдвиньте его до знакового бита, а затем сдвиньте его с расширением знака до конца, и вы получите либо all-ones, либо all-zeroes.
x + (( y -x) & (((!!condition)<<31)>>31)
Это зависит от платформы.
x + (y * (condition))
?