SSE2具有在单精度浮点数和32位整数之间转换向量的指令.
_mm_cvtps_epi32()_mm_cvtepi32_ps()但是没有双精度和64位整数的等价物.换句话说,他们失踪了:
_mm_cvtpd_epi64()_mm_cvtepi64_pd()似乎AVX也没有它们.
模拟这些内在函数的最有效方法是什么?
我处于需要计算类似事物的情况size_t s=(size_t)floorf(f);.也就是说,参数是一个浮点数,但它有一个整数值(假设floorf(f)它足够小,可以准确表示).在优化这一点的同时,我发现了一些有趣
以下是从float整数转换(GCC 5.2.0 -O3).为清楚起见,给出的转换是测试函数的返回值.
这是int32_t x=(int32_t)f:
cvttss2si eax, xmm0
ret
Run Code Online (Sandbox Code Playgroud)
这是uint32_t x=(uint32_t)f:
cvttss2si rax, xmm0
ret
Run Code Online (Sandbox Code Playgroud)
这是int64_t x=(int64_t)f:
cvttss2si rax, xmm0
ret
Run Code Online (Sandbox Code Playgroud)
最后,这是uint64_t x=(uint64_t)f;:
ucomiss xmm0, DWORD PTR .LC2[rip]
jnb .L4
cvttss2si rax, xmm0
ret
.L4:
subss xmm0, DWORD PTR .LC2[rip]
movabs rdx, -9223372036854775808
cvttss2si rax, xmm0
xor rax, rdx
ret
.LC2:
.long 1593835520
Run Code Online (Sandbox Code Playgroud)
最后一个比其他的复杂得多.此外,Clang和MSVC表现相似.为方便起见,我将其翻译成伪C:
float lc2 = (float)(/* 2^63 - 1 */);
if (f<lc2) …Run Code Online (Sandbox Code Playgroud) 我想在GHC Haskell编译器中实现C的uint-to- doublecast 的等价物.我们已经实现了int-到- double使用FILD或CVTSI2SD.是否有这些操作的无符号版本,或者我应该uint将转换前的最高位置零(从而丢失范围)?