如何使用SSE将_m128i转换为unsigned int? [英] How do I convert _m128i to an unsigned int with SSE?

查看:287
本文介绍了如何使用SSE将_m128i转换为unsigned int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经制作了一个分色图片的功能。

I have made a function for posterizing images.

// =(
#define ARGB_COLOR(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

inline UINT PosterizeColor(const UINT &color, const float &nColors)
{
    __m128 clr = _mm_cvtepi32_ps(  _mm_cvtepu8_epi32((__m128i&)color)  );

    clr = _mm_mul_ps(clr,  _mm_set_ps1(nColors / 255.0f)  );
    clr = _mm_round_ps(clr, _MM_FROUND_TO_NEAREST_INT);
    clr = _mm_mul_ps(clr, _mm_set_ps1(255.0f / nColors)  );

    __m128i iClr = _mm_cvttps_epi32(clr);

    return ARGB_COLOR(iClr.m128i_u8[12],
                      iClr.m128i_u8[8],
                      iClr.m128i_u8[4],
                      iClr.m128i_u8[0]);
}

in第一行,我将颜色解压缩成4个浮点数,但我找不到正确的反向方法。

in the first line, I unpack the color into 4 floats, but I can't find the proper way to do the reverse.

我搜索了SSE文档和找不到 _mm_cvtepu8_epi32的反向

I searched through the SSE docs and could not find the reverse of _mm_cvtepu8_epi32

是否存在?

推荐答案

不幸的是,即使在AVX中也没有指令可以做到这一点(我没有注意到)。因此,您必须像现在一样手动完成。

Unfortunately, there's no instruction to do that even in AVX (none that I'm aware of). So you will have to do it manually like are right now.

但是,您当前的方法非常不理想,而且您依赖 .m128i_u8 这是一个MSVC扩展。根据我对MSVC的经验,它将使用对齐的缓冲区来访问各个元素。由于部分字访问,这会受到非常严重的惩罚。

However, your current method is very sub-optimal and you're relying on .m128i_u8 which is an MSVC extension. Based on my experience with MSVC, it will use an aligned buffer to access the individual elements. This has a very heavy penalty because of partial-word access.

而不是 .m128i_u8 ,请使用 _mm_extract_epi32() 。这是在SSE4.1中。但是你已经依赖SSE4.1与 _mm_cvtepu8_epi32()

这种情况特别糟糕,因为你'使用1字节粒度。如果您使用的是2字节(16位整数)粒度,那么使用 shuffle intrinsics

This situation is particularly bad since you're working with 1-byte granularity. If you were working with 2-byte (16-bit integer) granularity instead, there is an efficient solution using shuffle intrinsics.

这篇关于如何使用SSE将_m128i转换为unsigned int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆