SSE指令

目录

一、数据类型

__m128

 __m128i

__m128d

二、函数命名约定

三、指令

3.1 初始化函数

3.1.1 从内存中加载数据

__m128i _mm_loadu_si128 (__m128i const* mem_addr):

__m128i _mm_loadl_epi64 (__m128i const* mem_addr):

__m128 _mm_load_ps (float const* mem_addr) :

__m128 _mm_load1_ps (float const* mem_addr):

__m128 _mm_maskload_ps (float const * mem_addr, __m128i mask) :

3.1.2 用标量值初始化

__m128 _mm_set1_ps (float a):

__m128 _mm_set_ps (float e3, float e2, float e1, float e0):

_mm_set1_epi8 (char a):

_mm_set_epi8 (char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0):

__m128 _mm_setzero_ps (void):

 __m128i _mm_setzero_si128 ():

3.2 变量存储

void _mm_storeu_si128 (__m128i* mem_addr, __m128i a):

void _mm_storel_epi64 (__m128i* mem_addr, __m128i a):

3.3 算术操作

 __m128i _mm_add_epi32 (__m128i a, __m128i b):        

__m128i _mm_sub_epi32 (__m128i a, __m128i b) :

3.4 类型转换

__m128 _mm_cvtepi32_ps (__m128i a):

__m128i _mm_cvtps_epi32 (__m128 a):

3.5 pack类

__m128i _mm_packs_epi32 (__m128i a, __m128i b):

__m128i _mm_packus_epi16 (__m128i a, __m128i b):

__m128i _mm_unpacklo_epi8 (__m128i a, __m128i b):

__m128i _mm_unpacklo_epi16 (__m128i a, __m128i b):


一、数据类型

        SSE指令有3种数据类型,分别为__m128、__m128i、__m128d。每一种类型都以"__"+"m"+“vector的位长度”构成。

  • __m128

         包含4个float类型数据的向量

  •  __m128i

        包含若干个整型数据的向量,如char、short、int、unsigned long long等。例如128位的vector可以16个char、8个short、4个int,这些整型既可以是有符号的也可以是无符号的。

  • __m128d

        包含2个double类型数据的向量。

二、函数命名约定

        _mm_<name>_<data_type>

  • <name>:描述了内联函数的算术操作。
  • <data_type>:标识函数主要参数的数据类型

三、指令

3.1 初始化函数

3.1.1 从内存中加载数据

  • __m128i _mm_loadu_si128 (__m128i const* mem_addr):

        从内存中读入一个128位的整型数据放到dst中(地址无需对齐)。

dst[127:0] := MEM[mem_addr+127:mem_addr]
  • __m128i _mm_loadl_epi64 (__m128i const* mem_addr):

        从内存中读入一个64位的整型数据放到dst的第一个元素中(寄存器是128位,则第一个元素是低64位)。

dst[63:0] := MEM[mem_addr+63:mem_addr]
dst[MAX:64] := 0
  • __m128 _mm_load_ps (float const* mem_addr) :

         从内存中读入128位(由4个32位float组成),存入128位的vector中。

dst[127:0] := MEM[mem_addr+127:mem_addr]
  • __m128 _mm_load1_ps (float const* mem_addr):

         从内存中读入一个32位float,然后广播到dst的所有元素。

dst[31:0] := MEM[mem_addr+31:mem_addr]
dst[63:32] := MEM[mem_addr+31:mem_addr]
dst[95:64] := MEM[mem_addr+31:mem_addr]
dst[127:96] := MEM[mem_addr+31:mem_addr]
  • __m128 _mm_maskload_ps (float const * mem_addr, __m128i mask) :

        从内存中读入128位(4个float),根据mask的真假赋值。

FOR j := 0 to 3
	i := j*32
	IF mask[i+31]
		dst[i+31:i] := MEM[mem_addr+i+31:mem_addr+i]
	ELSE
		dst[i+31:i] := 0
	FI
ENDFOR
dst[MAX:128] := 0

3.1.2 用标量值初始化

  • __m128 _mm_set1_ps (float a):

        对 dst 的所有元素广播单精度 (32 位) 浮点值,dst中实际存了4个相同的值。

FOR j := 0 to 3
	i := j*32
	dst[i+31:i] := a[31:0]
ENDFOR
  • __m128 _mm_set_ps (float e3, float e2, float e1, float e0):

        输入4个值初始化变量

dst[31:0] := e0
dst[63:32] := e1
dst[95:64] := e2
dst[127:96] := e3
  • _mm_set1_epi8 (char a):

        对 dst 的所有元素广播字符型(8 位),dst中实际存了16个相同的值。

FOR j := 0 to 15
	i := j*8
	dst[i+7:i] := a[7:0]
ENDFOR
  • _mm_set_epi8 (char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0):

        用提供的16个char型值去初始化。

dst[7:0] := e0
dst[15:8] := e1
dst[23:16] := e2
dst[31:24] := e3
dst[39:32] := e4
dst[47:40] := e5
dst[55:48] := e6
dst[63:56] := e7
dst[71:64] := e8
dst[79:72] := e9
dst[87:80] := e10
dst[95:88] := e11
dst[103:96] := e12
dst[111:104] := e13
dst[119:112] := e14
dst[127:120] := e15
  • __m128 _mm_setzero_ps (void):

        给128位浮点变量赋零。

dst[MAX:0] := 0
  •  __m128i _mm_setzero_si128 ():

         给128位整型变量赋零。

dst[MAX:0] := 0

3.2 变量存储

  • void _mm_storeu_si128 (__m128i* mem_addr, __m128i a):

        将128位的整型数据存到128位的整型没存中。

MEM[mem_addr+127:mem_addr] := a[127:0]
  • void _mm_storel_epi64 (__m128i* mem_addr, __m128i a):

        将变量a中的第一个64位整型数存到dst中

MEM[mem_addr+63:mem_addr] := a[63:0]

3.3 算术操作

  •  __m128i _mm_add_epi32 (__m128i a, __m128i b):        

        将 a+b 操作按32位进行处理,其中32位不能有溢出。

FOR j := 0 to 3
	i := j*32
	dst[i+31:i] := a[i+31:i] + b[i+31:i]
ENDFOR
  • __m128i _mm_sub_epi32 (__m128i a, __m128i b) :

        将 a-b 操作按32位进行处理,其中32位不能有溢出。

FOR j := 0 to 3
	i := j*32
	dst[i+31:i] := a[i+31:i] - b[i+31:i]
ENDFOR

3.4 类型转换

  • __m128 _mm_cvtepi32_ps (__m128i a):

        将a中包裹的 32 位整型数转换为包裹的32 位浮点数,并将结果存储在 dst 中(该包中有4个数)。

FOR j := 0 to 3
	i := 32*j
	dst[i+31:i] := Convert_Int32_To_FP32(a[i+31:i])
ENDFOR
  • __m128i _mm_cvtps_epi32 (__m128 a):

         将a中包裹的 32 位浮点数转换为包裹的32 位整型数,并将结果存储在 dst 中(该包中有4个数)。

FOR j := 0 to 3
	i := 32*j
	dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i])
ENDFOR

3.5 pack类

  • __m128i _mm_packs_epi32 (__m128i a, __m128i b):

        将a中包裹好的 32 位带符号的整型数截断成 16 位带符号的整型数,并将结果存储在 dst 中。 b也做相同操作。

dst[15:0] := Saturate16(a[31:0])
dst[31:16] := Saturate16(a[63:32])
dst[47:32] := Saturate16(a[95:64])
dst[63:48] := Saturate16(a[127:96])
dst[79:64] := Saturate16(b[31:0])
dst[95:80] := Saturate16(b[63:32])
dst[111:96] := Saturate16(b[95:64])
dst[127:112] := Saturate16(b[127:96])
  • __m128i _mm_packus_epi16 (__m128i a, __m128i b):

        将a中包裹好的 16 位带符号的整型数截断成 8 位无符号的整型数,并将结果存储在 dst 中。 b也做相同操作。

dst[7:0] := SaturateU8(a[15:0])
dst[15:8] := SaturateU8(a[31:16])
dst[23:16] := SaturateU8(a[47:32])
dst[31:24] := SaturateU8(a[63:48])
dst[39:32] := SaturateU8(a[79:64])
dst[47:40] := SaturateU8(a[95:80])
dst[55:48] := SaturateU8(a[111:96])
dst[63:56] := SaturateU8(a[127:112])
dst[71:64] := SaturateU8(b[15:0])
dst[79:72] := SaturateU8(b[31:16])
dst[87:80] := SaturateU8(b[47:32])
dst[95:88] := SaturateU8(b[63:48])
dst[103:96] := SaturateU8(b[79:64])
dst[111:104] := SaturateU8(b[95:80])
dst[119:112] := SaturateU8(b[111:96])
dst[127:120] := SaturateU8(b[127:112])
  • __m128i _mm_unpacklo_epi8 (__m128i a, __m128i b):

        取整型变量a 和 b 的低64位,然后按 8 位整数交替存储(无截断操作),并将结果存储在 dst 中。

DEFINE INTERLEAVE_BYTES(src1[127:0], src2[127:0])
{
	dst[7:0] := src1[7:0] 
	dst[15:8] := src2[7:0] 
	dst[23:16] := src1[15:8] 
	dst[31:24] := src2[15:8] 
	dst[39:32] := src1[23:16] 
	dst[47:40] := src2[23:16] 
	dst[55:48] := src1[31:24] 
	dst[63:56] := src2[31:24] 
	dst[71:64] := src1[39:32]
	dst[79:72] := src2[39:32] 
	dst[87:80] := src1[47:40] 
	dst[95:88] := src2[47:40] 
	dst[103:96] := src1[55:48] 
	dst[111:104] := src2[55:48] 
	dst[119:112] := src1[63:56] 
	dst[127:120] := src2[63:56] 
	RETURN dst[127:0]	
}
dst[127:0] := INTERLEAVE_BYTES(a[127:0], b[127:0])
  • __m128i _mm_unpacklo_epi16 (__m128i a, __m128i b):

         取整型变量a 和 b 的低64位,然后按 16 位整数交替存储(无截断操作),并将结果存储在 dst 中。

DEFINE INTERLEAVE_WORDS(src1[127:0], src2[127:0])
 {
	dst[15:0] := src1[15:0] 
	dst[31:16] := src2[15:0] 
	dst[47:32] := src1[31:16] 
	dst[63:48] := src2[31:16] 
	dst[79:64] := src1[47:32] 
	dst[95:80] := src2[47:32] 
	dst[111:96] := src1[63:48] 
	dst[127:112] := src2[63:48] 
	RETURN dst[127:0]	
}
dst[127:0] := INTERLEAVE_WORDS(a[127:0], b[127:0])

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值