Як можна вставити NaN в регістр xmm?


9

Для функції, яку я пишу, я хотів би повернути Nan, якщо введення не має сенсу.

Як я можу вставити NaN в реєстр xmm найпростішим способом?


1
Як визначити, який "вхід не має сенсу"? Якщо це результат порівняння, ви можете просто побіжно - або ваш "нормальний" результат за допомогою маски результату порівняння.
chtz

Відповіді:


13

Усі - це тихий (несигнальний, так само нормальний) 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 не вдався до перевірки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.