What is the fastest way to convert float to int on x86

前端 未结 10 2248
轻奢々
轻奢々 2020-11-28 11:26

What is the fastest way you know to convert a floating-point number to an int on an x86 CPU. Preferrably in C or assembly (that can be in-lined in C) for any combination of

10条回答
  •  孤独总比滥情好
    2020-11-28 11:54

    Since MS scews us out of inline assembly in X64 and forces us to use intrinsics, I looked up which to use. MSDN doc gives _mm_cvtsd_si64x with an example.

    The example works, but is horribly inefficient, using an unaligned load of 2 doubles, where we need just a single load, so getting rid of the additional alignment requirement. Then a lot of needless loads and reloads are produced, but they can be eliminated as follows:

     #include 
     #pragma intrinsic(_mm_cvtsd_si64x)
     long long _inline double2int(const double &d)
     {
         return _mm_cvtsd_si64x(*(__m128d*)&d);
     }
    

    Result:

            i=double2int(d);
    000000013F651085  cvtsd2si    rax,mmword ptr [rsp+38h]  
    000000013F65108C  mov         qword ptr [rsp+28h],rax  
    

    The rounding mode can be set without inline assembly, e.g.

        _control87(_RC_NEAR,_MCW_RC);
    

    where rounding to nearest is default (anyway).

    The question whether to set the rounding mode at each call or to assume it will be restored (third party libs) will have to be answered by experience, I guess. You will have to include float.h for _control87() and related constants.

    And, no, this will not work in 32 bits, so keep using the FISTP instruction:

    _asm fld d
    _asm fistp i
    

提交回复
热议问题