Для функції, яку я пишу, я хотів би повернути Nan, якщо введення не має сенсу.
Як я можу вставити NaN в реєстр xmm найпростішим способом?
Для функції, яку я пишу, я хотів би повернути Nan, якщо введення не має сенсу.
Як я можу вставити NaN в реєстр xmm найпростішим способом?
Відповіді:
Усі - це тихий (несигнальний, так само нормальний) NaN, який ви хочете. Найпростіший спосіб створити його - за допомогою SSE2 pcmpeqd xmm0,xmm0
встановити кожен біт у регістрі на 1
, тобто ціле число доповнення 2 -1
. ( Встановіть всі біти в регістрі процесора на 1 ефективно / Які найкращі послідовності інструкцій для генерації векторних констант на льоту? )
Насправді це -NaN
- біт знаків встановлений. Розглянемо цілий правий зсув ( 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
, навіть якщо це було давно, а ціле число SIMD взагалі вже вийшло з ладу.)
Ви навіть можете це зробити без гілок, якщо використовуватимете : cmpsd
або cmppd
ви можете orps
маскувати 0 / -1 в результаті, щоб зробити його NaN або незмінним. Якщо якийсь інший розрахунок встановить (або вже буде) встановити недійсний прапор FP або якщо ви цього не хвилюєте, все налаштовано.
Остерігайтеся подовження критичного шляху додатковим cmp / або; якщо ви очікуєте, що це дуже рідко, ви можете все-таки порівняти і розв'язати , наприклад, з movmskpd
/ test eax,eax
/ jnz
на cmppd результату, щоб побачити, чи встановлено будь-який біт => один із елементів SIMD не вдався до перевірки.