2013-03-22 3 views
14

xmm SSE2 레지스터에서 32 비트 모드로 64 비트 정수 값을로드하는 가장 좋은 방법은 무엇입니까?배정도 SSE2 레지스터에 64 비트 정수를로드하는 가장 좋은 방법은 무엇입니까?

64 비트 모드에서는 cvtsi2sd을 사용할 수 있지만 32 비트 모드에서는 32 비트 정수 만 지원합니다.

지금까지 I 훨씬 넘어서 발견되지 않은 : movsd

  • 부하 높은 32 비트 부분 레지스터 xmm에 추가, 2^32 곱

    • 사용 fild, fstp 후 적층 할 낮은 32 비트

    첫 번째 솔루션은 천천히, 두 번째 솔루션은 정밀도 손실 (편집 소개 할 수 있습니다 :를 그리고 3 낮은 있기 때문에, 어쨌든 느린 2 비트는 부호없는 것으로 변환해야합니다 ...)

    더 좋은 방법이 있습니까?

  • +0

    부동 소수점으로 상위 32 비트에 2 ** 32를 곱하면 이들을 잘라내거나 반올림하지 않습니다. 32 비트를 더하는 경우에만 합계가 반올림되거나 잘립니다. 첫 번째 방법으로 얻을 수있는 것입니다. 내가 누락 된 것이 아니라면이 두 메서드는 동일합니다 (성능 제외). –

    +3

    FWIW gcc는 첫 번째 방법 (fild, fst, movsd)을 사용하는 것 같습니다. –

    +0

    두 번째 옵션이 실제로 느리다. 실제로 낮은 32 비트 용으로 cvtsi2sd를 잘못 사용했지만 서명이없는 것으로 변환해야 CPU 명령어가 존재하지 않으므로 속도가 느려진다. –

    답변

    9

    두 번째 옵션 일 수 있습니다. 다소 다루기 힘듭니다. 귀하의 64 비트 숫자는 처음에는 edx : eax라고 가정합니다.

    cvtsi2sd xmm0, edx    // high part * 2**-32 
    mulsd xmm0, [2**32 from mem] // high part 
    movsd xmm2, [2**52 from mem] 
    movd  xmm1, eax 
    orpd  xmm1, xmm2    // (double)(2*52 + low part as unsigned) 
    subsd xmm1, xmm2    // (double)(low part as unsigned) 
    addsd xmm0, xmm1    // (double)(high part + low part as unsigned) 
    

    마지막 작업을 제외한 모든 작업은 정확하므로 정확하게 반올림됩니다. 이 변환은 입력이 0이고 mxcsr이 반올림 - 음수 - 무한대로 설정된 경우 -0.0을 생성합니다. 이것은 IEEE-754 규격을 제공하는 것을 목표로하는 컴파일러 용 런타임 라이브러리에서 사용되는 경우 처리해야하지만 대부분의 경우에는 문제가되지 않습니다.