Ваше изменение выглядит эквивалентно мне, если предположить, что gravityVelX
никогда не является NaN.Логическое значение преобразуется в 0.0
или 1.0
.
Если ваше изменение позволяет выполнить оптимизацию, которая ранее была невозможна или не была выполнена, то, возможно, по умолчанию ICC, равный -ffast-math
, вызывает проблему.(По умолчанию это -fp-model fast=1
: https://software.intel.com/en-us/node/522979. Это похоже на -ffast-math
в gcc, которая позволяет оптимизировать изменения, которые меняют результат.)
Кстати, вы можете получить лучшие результаты с этим,потому что SSE2 может делать это напрямую
resultVelX += r > COLLISION_DISTANCE ? gravityVelX : 0.0;
Это наиболее прямо выражает в C то, что вы хотите, чтобы компилятор испускал
(cmpps r,collision_distance
/ andps gravityVelX, cmp_result
/ addps resultVelX, and_result
),Вы на самом деле не хотите или не должны умножать, и создание фактической 1.0 более громоздко, чем просто добавление 0 или того, что вы хотите.
x86 SIMD-команды сравнения создают вектор из всех нулей или всех единиц.который вы можете использовать в качестве маски И непосредственно.Это прекрасно работает для условного сложения, поскольку битовый шаблон со всеми нулями представляет IEEE 754 0.0
, а ноль - аддитивный идентификатор.
(Без -ffast-math
компиляторы не всегда могут предположить, что добавление 0.0
не работает. Я думаю, что из-за нулевого знака. Обычно вам нужны дополнительные опции, чтобы сообщить компиляторам, что операции FP могут вызывать исключения, то есть, что исключения не маскируются и, таким образом, являются видимым побочным эффектом. В любом случае, с параметрами ICC по умолчанию,он должен иметь возможность самостоятельно конвертировать if
в код без ответвлений, но если у него возникают проблемы, удерживая его вручную с троичным, который всегда добавляет что-то , это путь.)