xmm 레지스터에 NaN을 어떻게 삽입 할 수 있습니까?


9

내가 쓰고있는 함수의 경우 입력이 이해되지 않으면 Nan을 반환하고 싶습니다.

가장 쉬운 방법으로 NaN을 xmm 레지스터에 삽입하려면 어떻게 해야합니까?


1
어떤 "입력이 이해가되지 않는지"를 어떻게 결정합니까? 이것이 비교의 결과라면 비교 결과 마스크를 사용하여 비트 단위 또는 "정상"결과를 얻을 수 있습니다.
chtz

답변:


13

All-ones는 조용하고 (신호가없는, 일명 일반) NaN이며, 원하는 것입니다. 하나를 생성하는 가장 쉬운 방법은 SSE2 pcmpeqd xmm0,xmm0를 사용하여 레지스터의 모든 비트 ( 1예 : 2의 보수 정수)를 설정하는 것 -1입니다. ( CPU 레지스터의 모든 비트를 효율적으로 1로 설정하십시오. / 벡터 상수를 즉시 생성하는 가장 좋은 명령 시퀀스는 무엇입니까? )

실제로 -NaN부호 비트가 설정됩니다. 바람직하지 않은 경우 정수 오른쪽 시프트 ( psrld xmm0,1)를 고려 하거나 0/0 ( 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, xmm0xmm0이 pcmpeqd이전에 있고 정수 SIMD uop가 이미 종료 된 경우에도 xmm1 입력에서 xmm1 출력으로 지연 시간이 추가로 발생 합니다.)


당신은 당신이 사용하는 경우 branchlessly 그것을 할 수있을 것 cmpsdcmppd: 당신이 수 orps결과에 그 0 / -1 마스크는 NaN이 나 변경을 할 수 있습니다. 다른 계산으로 인해 FP- 잘못된 플래그가 설정되거나 이미 설정되어 있거나 신경 쓰지 않으면 모든 설정이 완료된 것입니다.

추가 cmp / 또는로 중요한 경로를 연장하지 않도록주의하십시오. 매우 드문 것으로 예상 되는 경우 cmppd 결과에서 movmskpd/ test eax,eax/ jnz를 사용하여 비교하고 분기 하여 비트 중 하나가 설정되었는지 => SIMD 요소 중 하나가 검사에 실패했는지 확인할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.