Как вы определяете, какой «вклад не имеет смысла»? Если это результат сравнения, вы можете просто поразрядно - или ваш «нормальный» результат с маской результата сравнения.
Это на самом деле -NaN- бит знака установлен. Рассмотрим целое число вправо shift ( psrld xmm0,1) или разделить на ноль / ноль ( xorps xmm0,xmm0/ divpd xmm0,xmm0), если это нежелательно.
Математические функции, которые хотят возвращать NaN, часто также хотят убедиться, что бит неверного исключения FP установлен в MXCSR (или фактически вызовет исключение, если ваш вызывающий абонент разоблачил это исключение). Для того, чтобы сделать что , вы можете умножить или добавить NaN с собой. например
...
.error_return_path:
pcmpeqd xmm0, xmm0
mulsd xmm0, xmm0 ; Cause an FP-invalid operation.
ret
Или mulssдля одинарной точности float. mulpd/ mulpsтакже будет уместно.
Битовый шаблон для умножения или добавления NaN с NaN определенно все еще является NaN, и все равно должен быть такой же полезной нагрузкой, так что все равно единицами.
Наличие возвращаемого значения в результате mulsdили addsd(или divsd) также имеет то преимущество, что если вызывающий использует этот регистр несколько раз в цикле, у него не будет задержки обхода при пересечении домена. (В семействе Sandybridge это длится вечно. Например, у каждого addsd xmm1, xmm0будет дополнительный цикл задержки от входа xmm1 до выхода xmm1, если xmm0 пришло pcmpeqd, даже если это было давно, и uop с целочисленным SIMD уже удалился.)
Вы можете даже сделать это без ответвлений, если вы используете cmpsdили cmppd: вы можете использовать orpsэту маску 0 / -1 в результате, чтобы сделать его NaN или неизменным. Если какой-либо другой расчет (или уже будет) установит флаг FP-invalid или если вам это не важно, все готово.
Остерегайтесь удлинения критического пути с помощью дополнительных cmp / или; если вы ожидаете, что это очень редко, вы все равно можете сравнить и перейти, например, с помощью movmskpd/ test eax,eax/ jnzдля результата cmppd, чтобы увидеть, был ли установлен какой-либо бит => один из элементов SIMD не прошел проверку.
Ответы:
All-One - это тихий (не сигнальный, нормальный) NaN, который вам нужен. Самый простой способ получить его - использовать SSE2
pcmpeqd xmm0,xmm0
для установки каждого бита в регистре1
, то есть целого числа дополнения 2-1
. ( Установите все биты в регистре ЦП на 1 / Каковы наилучшие последовательности команд для генерации векторных констант на лету? )Это на самом деле
-NaN
- бит знака установлен. Рассмотрим целое число вправо shift (psrld xmm0,1
) или разделить на ноль / ноль (xorps xmm0,xmm0
/divpd xmm0,xmm0
), если это нежелательно.Математические функции, которые хотят возвращать NaN, часто также хотят убедиться, что бит неверного исключения FP установлен в MXCSR (или фактически вызовет исключение, если ваш вызывающий абонент разоблачил это исключение). Для того, чтобы сделать что , вы можете умножить или добавить NaN с собой. например
Или
mulss
для одинарной точностиfloat
.mulpd
/mulps
также будет уместно.Битовый шаблон для умножения или добавления NaN с NaN определенно все еще является NaN, и все равно должен быть такой же полезной нагрузкой, так что все равно единицами.
Наличие возвращаемого значения в результате
mulsd
илиaddsd
(илиdivsd
) также имеет то преимущество, что если вызывающий использует этот регистр несколько раз в цикле, у него не будет задержки обхода при пересечении домена. (В семействе Sandybridge это длится вечно. Например, у каждогоaddsd xmm1, xmm0
будет дополнительный цикл задержки от входа xmm1 до выхода xmm1, если xmm0 пришлоpcmpeqd
, даже если это было давно, и uop с целочисленным SIMD уже удалился.)Вы можете даже сделать это без ответвлений, если вы используете
cmpsd
илиcmppd
: вы можете использоватьorps
эту маску 0 / -1 в результате, чтобы сделать его NaN или неизменным. Если какой-либо другой расчет (или уже будет) установит флаг FP-invalid или если вам это не важно, все готово.Остерегайтесь удлинения критического пути с помощью дополнительных cmp / или; если вы ожидаете, что это очень редко, вы все равно можете сравнить и перейти, например, с помощью
movmskpd
/test eax,eax
/jnz
для результата cmppd, чтобы увидеть, был ли установлен какой-либо бит => один из элементов SIMD не прошел проверку.источник