답변:
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, xmm0
xmm0이 pcmpeqd
이전에 있고 정수 SIMD uop가 이미 종료 된 경우에도 xmm1 입력에서 xmm1 출력으로 지연 시간이 추가로 발생 합니다.)
당신은 당신이 사용하는 경우 branchlessly 그것을 할 수있을 것 cmpsd
나 cmppd
: 당신이 수 orps
결과에 그 0 / -1 마스크는 NaN이 나 변경을 할 수 있습니다. 다른 계산으로 인해 FP- 잘못된 플래그가 설정되거나 이미 설정되어 있거나 신경 쓰지 않으면 모든 설정이 완료된 것입니다.
추가 cmp / 또는로 중요한 경로를 연장하지 않도록주의하십시오. 매우 드문 것으로 예상 되는 경우 cmppd 결과에서 movmskpd
/ test eax,eax
/ jnz
를 사용하여 비교하고 분기 하여 비트 중 하나가 설정되었는지 => SIMD 요소 중 하나가 검사에 실패했는지 확인할 수 있습니다.