加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何使用SSE执行uint32 / float转换?

发布时间:2020-12-13 22:27:53 所属栏目:Windows 来源:网络整理
导读:在SSE中有一个函数_mm_cvtepi32_ps(__ m128i输入),它接受32位宽的有符号整数(int32_t)的输入向量,并将它们转换为浮点数. 现在,我想将输入整数解释为未签名.但是没有函数_mm_cvtepu32_ps,我找不到一个实现.你知道我在哪里可以找到这样的功能,或者至少对实现有
在SSE中有一个函数_mm_cvtepi32_ps(__ m128i输入),它接受32位宽的有符号整数(int32_t)的输入向量,并将它们转换为浮点数.

现在,我想将输入整数解释为未签名.但是没有函数_mm_cvtepu32_ps,我找不到一个实现.你知道我在哪里可以找到这样的功能,或者至少对实现有所暗示吗?
为了说明结果的差异:

unsigned int a = 2480160505; // 10010011 11010100 00222220 22222001   
float a1 = a; // 01001111 00010011 11010100 00222221;  
float a2 = (signed int)a; // 11001110 11011000 01010111 10000010

解决方法

此功能存在于AVX-512中,但是如果你不能等到那时我唯一可以建议的是将无符号int输入值转换为较小值的对,转换它们,然后再将它们一起添加,例如

inline __m128 _mm_cvtepu32_ps(const __m128i v)
{
    __m128i v2 = _mm_srli_epi32(v,1);     // v2 = v / 2
    __m128i v1 = _mm_sub_epi32(v,v2);     // v1 = v - (v / 2)
    __m128 v2f = _mm_cvtepi32_ps(v2);
    __m128 v1f = _mm_cvtepi32_ps(v1);
    return _mm_add_ps(v2f,v1f); 
}

UPDATE

如his answer中的@wim所述,上述解决方案对于UINT_MAX的输入值失败.这是一个更强大但效率稍低的解决方案,它应该适用于完整的uint32_t输入范围:

inline __m128 _mm_cvtepu32_ps(const __m128i v)
{
    __m128i v2 = _mm_srli_epi32(v,1);                 // v2 = v / 2
    __m128i v1 = _mm_and_si128(v,_mm_set1_epi32(1));  // v1 = v & 1
    __m128 v2f = _mm_cvtepi32_ps(v2);
    __m128 v1f = _mm_cvtepi32_ps(v1);
    return _mm_add_ps(_mm_add_ps(v2f,v2f),v1f);      // return 2 * v2 + v1
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读