如何使用SSE将_m128i转换为无符号整型?
How do I convert _m128i to an unsigned int with SSE?
我编写了一个图像隔色的函数。
// =(
#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]);
}
在第一行中,我将颜色解包为4个浮点数,但我找不到正确的方法来反向操作。
我搜索了SSE文档,找不到_mm_cvtepu8_epi32
的反向
存在吗?
您需要的是_mm_shuffle_epi8
和_mm_cvtsi128_si32
的组合:
static const __m128i shuffleMask = _mm_setr_epi8(0, 4, 8, 12, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1);
UINT color = _mm_cvtsi128_si32(_mm_shuffle_epi8(iClr, shuffleMask));
不幸的是,即使在AVX中也没有这样做的指令(据我所知没有)。所以你必须像现在这样手动操作。
然而,你目前的方法是非常次优的,你依赖于.m128i_u8
,这是一个MSVC扩展。根据我使用MSVC的经验,它将使用对齐的缓冲区来访问各个元素。由于部分字访问,这有一个非常重的惩罚。
用_mm_extract_epi32()
代替.m128i_u8
。这是在SSE4.1。但你已经依赖于SSE4.1与_mm_cvtepu8_epi32()
。
这种情况尤其糟糕,因为您使用的是1字节粒度。如果您使用的是2字节(16位整数)粒度,那么有一个使用shuffle intrinsic的有效解决方案。
相关文章:
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- CPP 如何在无符号整数值中使用布尔值?
- C++模板特征以指定任何无符号整型
- 无符号长整型VS无符号长型整型
- 如何根据位将有符号整数值转换为无符号整数值
- 是对定义良好的有符号整型进行位操作的结果
- 如何使用SSE将_m128i转换为无符号整型?
- 不能使用parameter作为无符号整型,通过引用传递
- 稍后在{}中添加无符号整型数组
- 无符号整型转换
- 如何工作与内存地址在C?它们是十六进数还是无符号整型
- c++无符号整型的位补码返回负值
- 由于头文件中无符号整型初始化,调试模式链接失败
- 如果枚举不能装入无符号整型,会发生什么情况?
- 在c++中将无符号整型重新解释为浮点型
- 将RGBA打包为无符号整型
- 64位向量的点积速度比32位无符号整型向量快两倍
- 如何将表示像素的字符数组读取为无符号整型
- 将16位无符号整型数组转换为32位浮点数组
- OpenMP - OpenMP 语句中的索引变量'for'必须具有有符号整型