CUDA: Почему побитовые операторы иногда быстрее, чем логические операторы?

Когда я сжимаю последний бит производительности из ядра, я обычно обнаруживаю, что замена логических операторов (&& и ||) побитовыми операторами (& и |) делает ядро ​​немного быстрее. Это наблюдалось при просмотре сводки времени ядра в CUDA Visual Profiler.

Итак, почему побитовые операторы быстрее, чем логические операторы в CUDA? Должен признаться, что они не всегда бывают быстрее, но много раз. Интересно, какая магия может дать это ускорение.

Отказ от ответственности: я знаю, что логические операторы короткого замыкания и побитовые операторы этого не делают. Я хорошо знаю, как эти операторы могут быть неправильно использованы, что приводит к неправильному коду. Я использую эту замену с осторожностью только тогда, когда результирующая логика остается неизменной, есть ускорение, и полученное таким образом ускорение имеет значение для меня: -)

Ответ 1

Логические операторы часто приводят к ветвям, особенно когда необходимо соблюдать правила оценки короткого замыкания. Для нормальных процессоров это может означать неправильное предсказание отрасли, а для CUDA это может означать разницу в деформации. Побитовые операции не требуют оценки короткого замыкания, поэтому поток кода является линейным (т.е. Без разветвления).

Ответ 2

A && В:

if (!A) {
  return 0;
}
if (!B) {
  return 0;
}
return 1;

A и B:

return A & B;

Это семантика, учитывая, что оценка A и B может иметь побочные эффекты (они могут быть функциями, которые изменяют состояние системы при оценке).

Существует много способов, которыми компилятор может оптимизировать случай A && B, в зависимости от типов A и B и контекста.

Ответ 3

Побитовые операции могут выполняться в регистрах на аппаратном уровне. Операции с регистром являются самыми быстрыми, это особенно верно, когда данные могут вписываться в регистр. Логические операции включают в себя оценку выражения, которая не может быть привязана к регистру. Обычно &, |, ^, → ... являются одними из самых быстрых операций и широко используются в высокопроизводительной логике.